UNION DISTINCT比OR上900万条记录更快?

时间:2013-08-20 17:32:18

标签: mysql sql innodb

我有一张InnoDB表,其中有900万条记录。

我以前有这样的查询

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,我是否在正确的路径上?或者还有其他更快的方法来执行我的查询吗?

感谢。

1 个答案:

答案 0 :(得分: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可以使用正确的索引实现此目的。