【问题标题】:Mysql performance with a large table大表的mysql性能
【发布时间】:2011-09-12 00:54:45
【问题描述】:

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

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

我怎样才能加快这些查询?谢谢

【问题讨论】:

  • 快速/脏提示:wherejoingroup by 子句中使用的任何字段都应该有一个索引。
  • 您是否添加了纬度、经度、姓氏和简历的索引? (即,当我输入此内容时,其他马克刚刚说了什么)

标签: mysql performance full-text-search


【解决方案1】:
  1. 对用于连接表的所有字段使用索引。
  2. 对您在 where 子句中使用的字段使用索引。
  3. 不要使用“select *”选择只选择您需要的字段
  4. Group by 对分组字段上的结果集进行排序,如果您在不同的字段 (或不同的顺序)上进行排序,则会强制进行额外的排序,从而减慢速度。
  5. MySQL 会进行快捷评估,将限制最大行数的条件放在 where 子句中。

  6. Select * with a group by 是另一种编写“消除重复行”的方式,如果您对表格进行布局,那么一开始就没有重复行,您也不需要 group by。这将大大加快您的查询速度。

  7. 将您的纬度和经度字段指定为类型点并在其上放置空间索引。我会给你一个链接,但我现在在 iphone 上,所以现在有点麻烦。

【讨论】:

  • 关于第 1 点和第 2 点,Btree 索引在这里没有帮助。他需要空间索引,而不是扫描大量的表。
【解决方案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 索引。充其量,它会抓取所有适合纬度或经度的位置,并沿着另一个维度调查潜在的行。您想要的是它只调查适合较小框的行。

为此,您需要spacial index

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——具体来说是 full text index

【讨论】:

  • SELECT firstname, lastname,date added,zip,resume_id FROM resumes WHERE ((latitude BETWEEN 34.3861330183 AND 35.7139349817) AND (longitude BETWEEN -87.9631695654 AND -86.3412124346)) 限制 0, 50
  • 在尝试“更改表恢复添加空间索引(纬度)”后,我收到错误 #1089 - 子部分键不正确;使用的键部分不是字符串,使用的长度比键部分长,或者存储引擎不支持唯一的子键
  • 确保您的表使用的是myisam engine。然后:CREATE SPATIAL INDEX resumes_sp_index ON resumes (latitude, longitude);CREATE FULLTEXT INDEX resumes_ft_index ON resumes (resume);
  • 问题是我的经度和纬度现在存储为浮点数,我想我需要将它们转换为空间字段类型。你对我应该使用哪种空间字段类型(几何、点等)以及我将如何去做有什么建议吗?非常感谢
  • 一个点似乎是正确的,但它可能是一个你需要它被索引的盒子......(在 Postgres 中,我会直接使用一个盒子,因为它最终会出现在无论如何索引。)由于mysql不允许索引我上次检查的表达式,您可能也想调查使用触发器填充它。
猜你喜欢
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2017-07-29
  • 2013-01-05
  • 2016-04-15
  • 2015-08-13
相关资源
最近更新 更多