mysql - 如何重写查询替换(或),(和)条件

标签 mysql query-performance sql-execution-plan

  1. 查询执行时间太长,大约需要 130 分钟。
  2. 表具有索引,但查询未使用索引。
  3. 表大小约为 3000 万条记录。
  4. 请帮助我通过更改(或)、(和)条件来重写查询。
  5. 该查询未在正常执行中使用,因此我们尝试使用强制索引,但没有成功。

查询:

SELECT customer_history.customer_id,
        customer_history.row_mod,
        customer_history.row_create,
        customer_history.event_id,
        customer_history.event_type,
        customer_history.new_value,
        customer_history.old_value
FROM customer_history FORCE INDEX (customer_history_n2)
WHERE customer_id >= 1
        AND customer_id < 5000000
        AND (customer_history.row_mod >= '2012-10-01')
        OR (
                customer_history.row_create >= '2012-10-01'
                AND customer_history.row_create < '2012-10-13'
                );


Table structure

    CREATE TABLE `customer_history` (
      `customer_id` int(11) NOT NULL,
      `row_mod` datetime DEFAULT NULL,
      `row_create` datetime DEFAULT NULL,
      `event_id` int(11) DEFAULT NULL,
      `event_type` varchar(45) DEFAULT NULL,
      `new_value` varchar(255) DEFAULT NULL,
      `old_value` varchar(255) DEFAULT NULL,
      KEY `customer_id1` (`customer_id`),
      KEY `new_value_n1` (`new_value`),
      KEY `customer_history_n1` (`row_create`),
      KEY `customer_history_n2` (`row_mod`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

解释计划:

+----+-------------+------------------+------+---------------------+------+---------+------+----------+-------------+
| id | select_type | table            | type | possible_keys       | key  | key_len | ref  | rows     | Extra       |
+----+-------------+------------------+------+---------------------+------+---------+------+----------+-------------+
|  1 | SIMPLE      | customer_history | ALL  | customer_history_n2 | NULL | NULL    | NULL | 18490530 | Using where |
+----+-------------+------------------+------+---------------------+------+---------+------+----------+-------------+
1 row in set (0

最佳答案

您可以尝试将此查询分成两部分:

SELECT customer_history.customer_id,
        customer_history.row_mod,
        customer_history.row_create,
        customer_history.event_id,
        customer_history.event_type,
        customer_history.new_value,
        customer_history.old_value
FROM customer_history
WHERE customer_id >= 1
        AND customer_id < 5000000
        AND (customer_history.row_mod >= '2012-10-01')

SELECT customer_history.customer_id,
        customer_history.row_mod,
        customer_history.row_create,
        customer_history.event_id,
        customer_history.event_type,
        customer_history.new_value,
        customer_history.old_value
FROM customer_history
WHERE  customer_history.row_create >= '2012-10-01'
       AND customer_history.row_create < '2012-10-13';

并查看其中哪一个需要更长的时间来执行和优化它们。为了获得与第一个查询相同的结果集,您可以在 MySQL 中UNION这两个查询,或者简单地从应用程序层单独执行它们并在那里连接结果集。

关于mysql - 如何重写查询替换(或),(和)条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14064905/

相关文章:

sql - 我如何优化这个更新每一行的 PostgreSQL 查询?

java - JPA 属性表达式与使用 'In'

postgresql - 从 plpgsql 中的 FOR 循环切换到基于集合的 SQL 命令

sql-server - 如何存储查询执行计划以便以后使用

postgresql - 缓慢的 Postgres 9.3 查询,再次

postgresql - Postgres 8.4 和 9.4 中的不同查询计划

java - 获取文件csv上传并添加mysql

mysql - 如何从第一行的列值的表中选择客户的最新记录

php - 将数据从 PHP 传递到 jQuery

Php数据库同步