AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 1792
Accepted
Patrick
Patrick
Asked: 2011-03-18 12:56:41 +0800 CST2011-03-18 12:56:41 +0800 CST 2011-03-18 12:56:41 +0800 CST

在 MySQL 中,WHERE 子句中列的顺序会影响查询性能吗?

  • 772

我在某些可能具有大量结果集的数据库查询上遇到性能问题。

有问题的查询,我AND在 WHERE 子句中有三个

条款的顺序重要吗?

如,如果我将 ASI_EVENT_TIME 子句放在首位(因为这会从任何子句中删除大部分结果。

这会改善查询的运行时间吗?

询问:

SELECT DISTINCT  activity_seismo_info.* 
FROM `activity_seismo_info` 
WHERE 
    activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL  AND 
    activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND 
    (
        activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND 
        activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
    ) 

ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC

查询说明:

+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+ 
| id | select_type | table   | type  | possible_keys             | key          | key_len | ref  | rows  | Extra                       |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+ 
|  1 | SIMPLE      | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5       | NULL | 65412 | Using where; Using filesort |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+

使用:

PHP 5.2

MySQL 5.0.51a-3ubuntu5.4

推进 1.3

Symfony 1.2.5

mysql performance
  • 6 6 个回答
  • 40674 Views

6 个回答

  • Voted
  1. Best Answer
    ypercubeᵀᴹ
    2011-03-18T13:31:33+08:002011-03-18T13:31:33+08:00

    我不这么认为。查询优化器应该足够聪明。

    您可以尝试重新排列 WHERE 子句,并查看 EXPLAINS 在每种情况下都告诉您相同的内容。


    关于可以做些什么来优化这个查询:ASI_EVENT_TIME 上有索引吗?(这是我认为对于这个查询最关键的,因为您也使用它对结果进行排序)。

    其他两个字段(ASI_SEISMO_ID 和 ASI_ACTIVITY_ID)是否有索引?

    如果您发布表结构,这将很有帮助。

    • 28
  2. Gaius
    2011-03-18T13:07:26+08:002011-03-18T13:07:26+08:00

    从文档中:

    如果表有一个多列索引,优化器可以使用索引的任何最左边的前缀来查找行。例如,如果您在 (col1, col2, col3) 上有一个三列索引,则您在 (col1)、(col1, col2) 和 (col1, col2, col3) 上有索引搜索功能。

    如果列不构成索引的最左前缀,则 MySQL 不能使用索引。

    所以是的,它应该与复合索引中列的顺序相同。

    • 19
  3. Morgan Tocker
    2011-03-22T12:48:48+08:002011-03-22T12:48:48+08:00

    不,没关系。

    优化器在解析 SQL 后立即执行一系列简单的转换——这就是其中之一。

    • 10
  4. Rick James
    2011-05-21T14:33:50+08:002011-05-21T14:33:50+08:00

    WHERE foo 和 bar

    优化与

    WHERE bar 和 foo

    然而,

    WHERE non-equal#1 AND non-equal#2

    无法优化这两个部分。例如,

    其中 a 介于 1 和 3 之间且 b > 17

    不能很好地利用 INDEX(a,b) 或 INDEX(b,a)

    换一种说法,首先使用 WHERE 子句中的任何“=”测试 AND 一起使用,然后可以处理一个非“=”(IN、BETWEEN、> 等)。可以有效优化的不超过一个。

    您的查询有 3 个这样的子句。

    事实证明,INDEX(EVENT_TIME) 可能是最有用的——它将帮助处理 AND 之一,并且可以用来避免 ORDER BY 的“文件排序”。

    如果没有重复的行(为什么会有重复的行?),然后摆脱 DISTINCT。这会导致更多的努力。

    询问性能问题时,请提供 SHOW CREATE TABLE 和 SHOW TABLE STATUS。

    更新...IN( list of constants )在某些情况下,较新的版本(例如 MySQL 5.7 )可以将=. 为了安全起见,请遵循以下顺序(每个部分都是可选的):

    1. 任意数量=。
    2. 一些INs.
    3. 最多一个范围。
    • 8
  5. Alix
    2016-09-29T06:18:56+08:002016-09-29T06:18:56+08:00

    MySQL 优化文档说:

    您可能很想重写查询以使算术运算更快,同时牺牲可读性。因为MySQL 会自动进行类似的优化,所以您通常可以避免这项工作,并将查询保留在更易于理解和维护的形式中。MySQL执行的一些优化如下:

    • ...

    • 对于连接中的每个表,构造一个更简单的 WHERE以获得对表的快速 WHERE 评估并尽快跳过行。

    • 查询每个表索引,并使用最佳索引,除非优化器认为使用表扫描更有效。曾经,根据最佳索引是否跨越超过 30% 的表来使用扫描,但固定百分比不再决定使用索引还是扫描之间的选择。优化器现在更加复杂,它的估计基于其他因素,例如表大小、行数和 I/O 块大小。

    这样,查询优化器忽略我们在查询中使用列的 HOW-order 是合理的(不仅 MySQL,SQL 是一种声明性语言,必须做我们想做的事情,而不是我们想要的事情)。

    但是我仍然喜欢在查询中对复合键的列进行相同的排序,但有时这是不可避免的,例如当我们使用 ORM 或 ActiveRecord 时,在 yii2 等一些框架中,自定义关系条件将附加到末尾“开启”条件,但我们仍然需要在应用程序的不同部分使用 QueryBuilders 的功能。

    • 1
  6. esengineer
    2011-03-18T17:34:09+08:002011-03-18T17:34:09+08:00

    在 WHERE/HAVING 子句中使用且具有高选择性(唯一值的数量/记录总数 > 10%~20%)的任何字段都必须被索引。

    因此,如果您的ASI_EVENT_TIME列有许多可能的值,请首先将它们全部索引。然后正如@ypercube 所说,尝试重新排列它们,看看 EXPLAIN 告诉你什么。应该都是一样的。

    此外,希望您看看Indexing SQL LIKE Filters。虽然这不是您需要的答案,但您仍将了解索引如何在幕后工作。

    *编辑: 请参阅下面评论中提供的链接以了解有关索引的更多信息。

    • -2

相关问题

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve