大表的 Mysql 性能

Mysql performance with a large table

提问人:sam 提问时间:6/10/2011 最后编辑:Johansam 更新时间:6/10/2011 访问量:648

问:

我有一个简历表 - 姓名、简历文本、邮政编码、名字、姓氏、经度、纬度、邮政编码......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

这个表上的查询一开始很慢,但之后同样的查询更快,我认为它正在缓存它......

如何加快这些查询速度?谢谢

MySQL 性能 全文搜索

评论

2赞 Marc B 6/10/2011
快速/肮脏的提示:在 or 子句中使用的任何字段都应该有一个索引。wherejoingroup by
0赞 mpen 6/10/2011
您是否添加了纬度、经度、姓氏和简历的索引?(即,当我输入这个时,其他 Marc 刚刚说了什么)

答:

0赞 Johan 6/10/2011 #1
  1. 对用于联接表的所有字段使用索引。
  2. 对 where 子句中使用的字段使用索引。
  3. 不要使用“选择 *”,仅选择所需的字段
  4. 分组依据对分组字段的结果集进行排序,如果对不同字段(或不同顺序)进行排序,则会强制进行额外的排序,从而减慢速度。
  5. MySQL做快捷方式计算,将限制最大行数的条件放在where子句的首位。

  6. 选择 * with a group by 是一种不同的写法,“消除重复的行”,如果你布置表格,这样就没有重复的行开始了,你也不需要分组。这将大大加快您的查询速度。

  7. 将纬度和经度字段指定为类型点,并在其上放置空间索引。我会给你一个链接,但我现在在 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不允许索引我上次检查的表达式,因此您可能还想研究使用触发器填充它。