我有一个非常简单的MYSQL表,有2列,我运行这个查询:
SELECT * FROM table WHERE (col1 = '123' AND col2 = '456')
OR (col1 = '456' AND col2 = '123')
Col1和col2是复合主键:PRIMARY KEY('col1','col2')
。两者中的每一个也是另一个表中主键的外键
当我为上述查询运行EXPLAIN命令时,我得到以下内容:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE table index PRIMARY,col2 col2 8 NULL 1 Using where; Using index
上述结果中的type
为index
,与All
非常相似,因此很可能在大型数据库中速度较慢。有没有办法改进上面的select
命令
答案 0 :(得分:3)
实际上likely to be slow on a large database
之类的陈述应该是一个红旗。
如果您要拥有大型数据集,那么分析和测试对于首先确定是否存在问题至关重要,然后确定是否足以解决开发时间和成本问题。通常这意味着微观优化不太可能对大多数代码库产生任何影响。
无论如何,让我们回答这个问题。
是的,假设我们使用索引文件,如果您有大量数据并查询此表,可能会通过将查询拆分为多个执行集而不是使用表达式运算符来优化它在查询中,如果您只是在示例中进行两次查询,则可以使用union
获得更高的性能,例如:
(
SELECT * FROM test
WHERE
(
col1 = 123 AND col2 = 456
)
)
UNION
(
SELECT * FROM test
WHERE
(
col1 = 456 AND col2 = 123
)
)
此查询的EXPLAIN
如下:
ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY KEY_LEN REF ROWS EXTRA
1 PRIMARY test ref PRIMARY PRIMARY 4 const 1 Using where; Using index
2 UNION test ref PRIMARY PRIMARY 4 const 2 Using where; Using index
(null) UNION RESULT <union1,2> ALL (null) (null) (null) (null) (null)
看一下这个SQL小提琴http://sqlfiddle.com/#!2/9dc07a/1/0的简单测试用例。
我在这篇文章中使用的语言,例如&#34;可能&#34;,&#34;可以&#34;等等是因为我没有在这个例子前面加载数亿条记录 - 我强烈建议你这样做,并更详细地评估和分析你的查询。
不幸的是,通过优化,总是一个明确而简单的答案来做x以获得更高的性能 - 查询优化器是一个复杂的野兽,有时候试图获得每一滴性能实际上都会削弱你的应用程序(I& #39; m来自此处的经验)所以请,除非你不得不担心这些微观优化 - 不要,如果你这样做,那么在决定采用方法之前进行评估,剖析和测试。
答案 1 :(得分:1)
基于成本的优化程序根据其对表的统计信息选择执行计划。它知道那里没有很多行,所以浪费时间做一些聪明的事情。显着增加表中的行数并确保您具有高基数(许多不同的值)并再次运行解释计划,您将看到执行更改。