提问人:sam 提问时间:6/10/2011 最后编辑:Johansam 更新时间:6/10/2011 访问量:648
大表的 Mysql 性能
Mysql performance with a large table
问:
我有一个简历表 - 姓名、简历文本、邮政编码、名字、姓氏、经度、纬度、邮政编码......500,000+ 行
我也以各种方式查询它:
按位置,例如:
1) SELECT * FROM resumes
WHERE ((latitude BETWEEN 44.3523845787 AND 45.6809474213)
AND (longitude BETWEEN -110.873064254 AND -108.993603746))
GROUP BY lastname,longitude
LIMIT 0, 50
by name
2) SELECT * from resumes
(MATCH(resume) AGAINST ('donald')) AS relevance
FROM resumes
WHERE (MATCH(resume) AGAINST ('donald'))
GROUP BY lastname,longitude
ORDER BY relevance DESC
LIMIT 0, 50
这个表上的查询一开始很慢,但之后同样的查询更快,我认为它正在缓存它......
如何加快这些查询速度?谢谢
答:
0赞
Johan
6/10/2011
#1
- 对用于联接表的所有字段使用索引。
- 对 where 子句中使用的字段使用索引。
- 不要使用“选择 *”,仅选择所需的字段。
- 分组依据对分组字段的结果集进行排序,如果对不同字段(或不同顺序)进行排序,则会强制进行额外的排序,从而减慢速度。
MySQL做快捷方式计算,将限制最大行数的条件放在where子句的首位。
选择 * with a group by 是一种不同的写法,“消除重复的行”,如果你布置表格,这样就没有重复的行开始了,你也不需要分组。这将大大加快您的查询速度。
- 将纬度和经度字段指定为类型点,并在其上放置空间索引。我会给你一个链接,但我现在在 iphone 上,所以现在有点麻烦。
评论
0赞
Denis de Bernardy
6/10/2011
关于第 1 点和第 2 点,Btree 索引在这里无济于事。他需要空间索引,而不是扫描表格的大块。
1赞
Denis de Bernardy
6/10/2011
#2
1) SELECT * FROM resumes
WHERE ((latitude BETWEEN 44.3523845787 AND 45.6809474213)
AND (longitude BETWEEN -110.873064254 AND -108.993603746))
GROUP BY lastname,longitude
LIMIT 0, 50
by name
这个几乎不能使用 btree 索引。充其量,它会抓取适合纬度或经度的所有位置,并沿着另一个维度调查潜在的行。您想要的是让它只调查适合较小框中的行。
为此,您需要一个空间索引。
2) SELECT * from resumes
(MATCH(resume) AGAINST ('donald')) AS relevance
FROM resumes
WHERE (MATCH(resume) AGAINST ('donald'))
GROUP BY lastname,longitude
ORDER BY relevance DESC
LIMIT 0, 50
同样,这还需要一种特殊的索引,它不是btree--一个具体的全文索引。
评论
0赞
sam
6/10/2011
SELECT firstname, lastname,dateadded,zip,resume_id FROM 恢复 WHERE ((纬度介于 34.3861330183 和 35.7139349817 之间)和(经度介于 -87.9631695654 和 -86.3412124346 之间)) 限制 0, 50
0赞
sam
6/10/2011
尝试“更改表恢复添加空间索引(纬度)”后,我收到错误#1089 - 不正确的子零件键;使用的键部分不是字符串,使用的长度长于键部分,或者存储引擎不支持唯一的子键
0赞
Denis de Bernardy
6/10/2011
确保您的表使用的是 MyISAM 引擎。then: 和 .CREATE SPATIAL INDEX resumes_sp_index ON resumes (latitude, longitude);
CREATE FULLTEXT INDEX resumes_ft_index ON resumes (resume);
0赞
sam
6/10/2011
问题是我的经度和纬度现在存储为浮点数,我想我需要将它们转换为空间字段类型。对于我应该使用哪种空间场类型(几何、点等)以及我将如何去做,您有什么建议吗?非常感谢
0赞
Denis de Bernardy
6/10/2011
一个点似乎是对的,但它可能是一个你需要它被索引的盒子......(在 Postgres 中,我会直接使用一个框,因为无论如何它最终都会出现在索引中。由于mysql不允许索引我上次检查的表达式,因此您可能还想研究使用触发器填充它。
评论
where
join
group by