MYSQL 在使用 OR 时提高查询性能

Posted

技术标签:

【中文标题】MYSQL 在使用 OR 时提高查询性能【英文标题】:MYSQL improve query performance when using OR 【发布时间】:2014-11-05 19:34:26 【问题描述】:

我有一个非常简单的 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

上述结果中的typeindex,与All 非常相似,因此在大型数据库上很可能会很慢。有没有办法改进上面的select命令

【问题讨论】:

【参考方案1】:

实际上,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 fiddle http://sqlfiddle.com/#!2/9dc07a/1/0 一个简单的测试用例。

我在这篇文章中使用的语言,例如“可能”、“可以”等,是因为我没有预先加载这个包含数亿条记录的示例 - 我强烈建议您这样做并评估和分析您的查询更详细。

不幸的是,对于优化,执行 x 以获得更好的性能并不总是一个清晰而简单的答案 - 查询优化器是一个复杂的野兽,有时试图获得每一滴性能实际上会削弱您的应用程序(我是从这里的经验说)所以请,除非您必须担心这些微优化 - 如果您这样做了,请不要在决定方法之前对其进行评估、分析和测试。

【讨论】:

【参考方案2】:

基于成本的优化器根据它对表的统计信息选择执行计划。它知道那里没有多少行,所以做一些聪明的事情是浪费时间。显着增加表中的行数并确保您具有高基数(许多不同的值)并再次运行解释计划,您将看到执行更改。

【讨论】:

以上是关于MYSQL 在使用 OR 时提高查询性能的主要内容,如果未能解决你的问题,请参考以下文章

如何提高查询性能?

将数据从 EBS 移动到临时存储会提高 MySQL 查询性能吗?

如何简化/提高这个 MySQL 查询的性能?

如何提高MYSQL查询的性能?

提高mysql数据库性能

提高Mysql查询性能