我一直在忙着改变一些SQL查询,以便它们看起来对人眼更具可读性,我还被告知它们可能会快5-10% .
以前的SQL语句看起来像这样 .
SELECT * FROM团队WHERE Team1 ='Joe Bloggs'或Team2 ='Joe Bloggs'或Team3 ='Joe Bloggs'
我改成了
SELECT * FROM teams WHERE'Joe Bloggs'IN(Team1,Team2,Team3)
新的查询大约慢了10倍,在检查了什么可能是因为我发现它没有使用任何索引,即使我试图强制索引它仍然不会使用它 .
该表有大约120,000行,我无法更改表格格式,因为我无法访问其他应用程序,使用它 . Team1,Team2,Team3列都是VARCHAR(45)
任何人都可以解释为什么索引用于原始查询而不是新查询?我已经阅读了大量的页面,但找不到答案,我已经读过可能的mysql确定它更快不使用索引,但不一定是这种情况,因为IN查询几乎慢了10倍 .
多个ORs SELECT(没有缓存运行1000次) - 12.863906860352经过IN SELECT(没有缓存运行1000次) - 122.73787903786已过去
感谢您的时间 .
4 回答
在查询中:
你正在比较(查找)一串列与字符串文字 . 优化器通常会使用搜索目标上的索引(在本例中为
Joe Bloggs
)来查找IN
子句中的值 . 但是,它可以帮助.742728_ t .另一方面,在您的第一个查询中:
MySQL将获取字符串文字,然后使用B树索引查找各种列 . 这表现得像你期望的那样 .
你有一个“倒IN”;优化器只会使用
column in (value1, value2, value3)
的索引 .但是,如果您在3列中的每一列上都有单独的索引,那么还有另一种方法可以产生比您的任何尝试都要好得多的性能:
该表将被查询3次,但每次都将使用索引 .
如果您确定不会有任何欺骗,或者您不介意欺骗,请将
UNION
更改为UNION ALL
以进一步加速(UNION
有额外的开销或重复数据删除) .计划A:使用
FULLTEXT (team1, team2, team3)
和MATCH(team1, team2, team3) AGAINST ('+Joe +Briggs' IN BOOLEAN MODE)
. 使用这种方法有很多注意事项,但是,如果它适用于您的情况,它会非常快 .计划B:尽管“无法更改表格格式”,您可以使用VIEW播放一些游戏,以避免跨列扩展阵列(团队) .
我不知道为什么性能会有所不同 - 在任何一种情况下似乎都没有使用索引 .
您可以像这样编写查询:
这可以使用
(Team1)
,(Team2, Team1)
和(Team3, Team2, Team1)
上的索引 .