我有一张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,我是否在正确的路径上?或者还有其他更快的方法来执行我的查询吗?
感谢。
答案 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
可以使用正确的索引实现此目的。