在django1.5中使用django debug toolbar分析SQL性能

为了分析WEB页面中SQL执行的性能,我试着用了一下django debug toolbar,感觉很方便。

简述一下在django 1.5中安装和使用的步骤:

1.  下载解压后,直接setup.py install

2. 完成之后到project文件夹下编辑settings.py文件: 继续阅读在django1.5中使用django debug toolbar分析SQL性能

(后续)记录一次MySQL关联表的优化

昨天写了篇日志,记录自己尝试去优化一个MySQL表。

最后因为对结果不满意,用了一种非常“高富帅”的方法解决问题,即把整个表都放到内存中提升查询性能。

现在回忆起来,性能问题确实是因为自己滥用MySQL造成的。

 

首先,再描述一下场景。

需要优化的是一个关联表,名为 album_tags ,300万条记录,只有3个字段:

id

album_id    外键关联到专辑的id, integer

tag_id           外键关联到标签的id, integer

应用中需要获取和某个tag关联的所有专辑,平均情形有几千个。

通过inner join两个表来取数据: album_tags 和album。

当时发现这个查询比较费时,有时多达四五秒。

排查从子查询开始,测试了类似语句:

select album_id from album_tags where tag_id = 8

当结果集数量较多时,这条语句会变慢,比如取出2万条的结果,可能就需要两三秒。

我尝试explain这个select查询,发现是有使用索引的。

实际上,最初为了提升查询性能,我还特别在tag_id这一列上建了个hash索引。

 

1. HASH(tag_id)分区优化

了解到索引没问题,我产生了第一个思路:分表, 继续阅读(后续)记录一次MySQL关联表的优化

多个列表在django模板中的并行迭代

自己接触django时间不长,刚遇到一点小问题,就是在django模板中如何并行迭代多个列表。

一开始我想到或许可以传入多个列表,然后在模板中使用forloop.counter变量的值去访问另一个列表的元素。

比如当我迭代list1和list2的时候,使用类似下面的代码:

{% for item in list1 %}

access list2 item via {{ list2.forloop.counter}}

{% endfor %}

forloop.counter是一个计数器,保存了当前的迭代计数器。然而,测试之后,发现这个方法是不可行的。

随后,我又测试了另一种方法,在模板中zip打包 list1和list2,然后通过序列解包来并行迭代。模板代码类似:

{% for item1,item2 in zip(list1, list2) %}

{{item1}} {{item2}}

{% endfor %}

不过, 这样也是不可行的。模板系统无法完成上面的工作。

那么,到底应该如何并行迭代呢?

继续阅读多个列表在django模板中的并行迭代

一个简单的python日期字符串格式化函数

之前从豆瓣音乐上爬了大概98万个专辑,包括各个专辑的参数。

为了处理专辑的发布日期,我写了一个简单的日期格式化函数。

豆瓣音乐上的日期没有统一规范,还包含不少错误,混乱,甚至无关的文字。

但正确出现的日期字符串,则主要有这几种形式:

10 December, 1991

30 June 1992

April 13, 1999

December 1994

June, 1992

2004 03

2002年08月05日

2004年6月

2002年

我需要的最终格式是:

2013-09-15

2013-09

2013

源代码在:  https://github.com/lijiejie/format-date-str

请传入一个unicode字符串

BeautifulSoup的innerHTML实现

innerHTML方法用于提取某个标签内部的HTML内容,多数HTML Parser都实现了该方法。

BeautifulSoup暂未提供innerHTML方法,但我们可以通过遍历子元素并拼接html来实现它。

例如,我需要获取豆瓣音乐上某个专辑的描述信息,它位于一个id为info的div中。

参考:http://music.douban.com/subject/1394539/

我需要图示部分的html代码:

info-div

这时只需要一行代码:

album_info = u''.join([unicode(x) for x in soup.find('div', id='info').contents]).strip()

值得注意的是,豆瓣音乐的网页编码是utf8,需要先decode utf8再parse。

而在Beautiful内部,所有对象都是unicode object。

contents属性返回所有child element的列表。

因为我是在windows中文版的系统下写这段脚本,当需要在命令提示符下输出内容的时候,还必须先encode gbk。

print album_info.encode('gbk', 'ignore')

 

参考链接:

http://stackoverflow.com/questions/8112922/beautifulsoup-innerhtml

扫描"豆瓣音乐"所有专辑的简单Python脚本

我需要一些音乐数据,而 豆瓣音乐 上相关数据是非常齐全的。

即使是十分小众、鲜有人听过的专辑,豆瓣也提供了较为详细的描述。

摆在我面前的第一个问题是,如何将豆瓣音乐上的专辑一网打尽,一个不遗漏地抓取到。

我们观察某个专辑的页面: http://music.douban.com/subject/1415369/

看到subject后跟着一串数字ID,这时候一个简单的思路已经出来了:

将id从1不断递增,扫描完所有的ID,检查哪些ID是存在的

又观察到大多数专辑页面上存在相关推荐,也就是那个“喜欢某某专辑的人也喜欢… …”。

这里存在一对N的超链接映射,最终形成了网络,于是可以有第二个思路:

将某个专辑加入队列,从它出发,通过 “也喜欢” 来获取新专辑,并将这些新专辑加入队尾

每完成一次操作,就从队列中删除队首的专辑

循环上面的过程,直到处理完队列中的所有元素

最终获取到的就是包含第一个元素的网

当然,上面的思路是有缺陷的,那些孤立的专辑无法被包括进来。

继续阅读扫描"豆瓣音乐"所有专辑的简单Python脚本