1

我有一个包含 +- 900 万条记录的 InnoDB 表。

我曾经有过这样的查询

SELECT
  my_primary_key
FROM
  my_table
WHERE
  col1 = 1 AND
  col2 = 2 AND
  (col3 = 'aaa' OR col4 = 'bbb' OR col5 = 'ccc')

我的表结构:

CREATE TABLE IF NOT EXISTS `my_table` (
  `my_primary_key` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `col1` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `col2` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `col3` varchar(255) NOT NULL,
  `col4` varchar(255) NOT NULL,
  `col5` varchar(255) NOT NULL,
  PRIMARY KEY (`my_primary_key`),
  KEY `col1` (`col1`),
  KEY `col2` (`col2`),
  KEY `col3` (`col3`),
  KEY `col4` (`col4`),
  KEY `col5` (`col5`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

根据我朋友的建议,我尝试将其更改为

SELECT my_primary_key FROM my_table WHERE col1 = 1 AND col2 = 2 AND col3 = 'aaa'
UNION DISTINCT
SELECT my_primary_key FROM my_table WHERE col1 = 1 AND col2 = 2 AND col4 = 'bbb'
UNION DISTINCT
SELECT my_primary_key FROM my_table WHERE col1 = 1 AND col2 = 2 AND col5 = 'ccc'

但是当我尝试查看正在运行的查询时,我发现“时间”仍然很高(8-20 秒之间)

SHOW FULL PROCESSLIST

使用 UNION DISTINCT 我在正确的道路上吗?还是有其他更快的方法来执行我的查询?

谢谢。

4

1 回答 1

0

我认为or通常会是最快的。但是,它似乎需要全表扫描。您可以尝试使用复合索引(col1, col2, col3, col4, col5, my_primary_key)而不是扫描。

如果每个子句都可以使用索引并且返回的union distinct行相对较少,则速度会更快。因此,请尝试使用以下索引运行它:

mytable(col1, col2, col3, my_primary_key)
mytable(col1, col2, col4, my_primary_key)
mytable(col1, col2, col5, my_primary_key)

在您的优化中,您试图避免全表扫描。可以通过union distinct正确的索引来实现这一点。

于 2013-08-20T17:35:45.133 回答