会员登录 | 会员注册 | 意见建议 | 网站地图

站长资源综合门户

当前位置:首页 > 站长学院 > 数据库 > MySQL数据库优化的一些笔记

MySQL数据库优化的一些笔记

时间:2012-05-17 18:14:05   作者:   来源:   点击:

*************************** 1. row ***************************

aid: 215001

id: 2e4b1a385c8aae40b3ec2af9153805ca446f2029

link: http://ncse/

title: NCSE

feed_url: NULL

update_time: 2012-05-12 10:47:15

state: queued

http_server: NULL

abstract: NULL

previous_id: 819a6e3c5edc1624a9b8f171d8d3ae269843785f

ref_count: 3

error: NULL

aid: 215001

1 row in set (0.06 sec)

mysql> EXPLAIN SELECT * FROM (SELECT aid FROM feed_urls ORDER BY aid LIMIT 215000, 1) d JOIN feed_urls u ON d.aid=u.aidG

*************************** 1. row ***************************

id: 1

select_type: PRIMARY

table:

type: system

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 1

Extra:

*************************** 2. row ***************************

id: 1

select_type: PRIMARY

table: u

type: const

possible_keys: aid

key: aid

key_len: 4

ref: const

rows: 1

Extra:

*************************** 3. row ***************************

id: 2

select_type: DERIVED

table: feed_urls

type: index

possible_keys: NULL

key: aid

key_len: 4

ref: NULL

rows: 211001

Extra: Using index

3 rows in set (0.15 sec)

 

耗时60ms,比之前的方法快了将近10倍。如果LIMIT语句里还有WHERE a=1,应该建立一个(a,aid)的索引。

话说,MySQL好像还是不能直接算出第21500条索引的位置呀,这种方法还是数了索引了,能算出来就直接0ms了。不过这样的效率,对于百万级的,还能应付吧。如果是千万级的或者像我之前在KS创建的一张上亿条记录的表(120G),这种方法就肯定不行了。

经过上述优化,打开最后一页的速度已经很快了(之前需要800ms,现在则为300ms左右)。

膜拜下这Burst 最低档次的VPS (30RMB/month)。

root@xiaoxia-pc:~/# ping feed.readself -n

PING app.readself (184.82.185.32) 56(84) bytes of data.

64 bytes from 184.82.185.32: icmp_req=1 ttl=45 time=161 ms

64 bytes from 184.82.185.32: icmp_req=2 ttl=45 time=161 ms

64 bytes from 184.82.185.32: icmp_req=3 ttl=45 time=161 ms

用同样的方法,优化了搜索引擎的排名算法。即排名过程中选取尽量少的值出来排序,排序后再JOIN一次获取结果的信息。

排序过程如下:

 

SELECT u.*, count_level(u.id) lv

FROM(

SELECT f.id, f.ref_count, MATCH(i,i.title) AGAINST (keywords) score

FROM feed_index i

JOIN feed_urls f ON f.id=i.id

WHERE MATCH(i,i.title) AGAINST (keywords)

ORDER BY score*0.5 + score*0.5*(ref_count/max_ref_count_in_result) DESC

LIMIT offset,10

) d JOIN feed_urls u ON u.id = d.id

 

目前处理10万记录的全文索引数据,MySQL还是可以满足的,就是不知道上百万之后,还能不能撑下去。撑不下去就依赖第三方的工具了,例如Sphinx

3. SELECT里的函数

给FeedDB增加了层次的显示。因为本人太懒,所以没有给数据库表增加一个记录深度的字段。所以,直接写了一个MySQL的自定义函数 count_level,用来统计通过parent_id一直找到顶层经过的路径长度(Level)。

 

CREATE DEFINER=`feeddb_rw`@`%` FUNCTION `count_level`(fid char(40)) RETURNS int(11)

BEGIN

SET @levels = 0;

SET @found = false;

WHILE NOT @found DO

SELECT previous_id INTO @prev_id FROM feed_urls WHERE id=fid;

IF @prev_id is null OR @prev_id = '' THEN

SET @found = true;

ELSE

SET @levels = @levels + 1;

SET fid = @prev_id;

END IF;

END WHILE;

IF @prev_id is null THEN

RETURN null;

分享到:

网友评论

推荐数据库

热门数据库