【问题标题】:MYSQL improve query performance when using ORMYSQL 在使用 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命令

【问题讨论】:

    标签: mysql sql performance


    【解决方案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】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-03
        • 2023-04-08
        • 2013-06-30
        • 1970-01-01
        • 2023-03-14
        • 2016-08-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多