使用布尔值优化Mysql查询

时间:2014-10-29 23:42:39

标签: mysql sql query-optimization

我有这张桌子:

CREATE TABLE IF NOT EXISTS `products` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `supplier_id` int(11) NOT NULL,
  `allowed` varchar(256) NOT NULL,
  `blocked` varchar(256) NOT NULL,
  `approved` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`product_id`),
  KEY `supplier_id` (`supplier_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

'approved'是布尔0/1字段
“阻止”和“允许”保留国家/地区代码,例如“US CA FR”

我运行此查询:

SELECT DISTINCT supplier_id 
FROM products 
WHERE (
    supplier_id=0 OR 
    supplier_id = 1207077 OR 
    supplier_id = 1207087 OR 
    supplier_id = 1207079 OR 
    supplier_id = 1207082 OR 
    supplier_id = 1207083 OR 
    supplier_id = 1207086 OR 
    supplier_id = 1207084 OR 
    supplier_id = 1207078 OR 
    supplier_id = 1207085 OR 
    supplier_id = 1207094 OR 
    supplier_id = 1207097 OR 
    supplier_id = 1207095 OR 
    supplier_id = 1207089 OR 
    supplier_id = 1207091
) AND (
    (`blocked` NOT LIKE '%US%' AND `allowed` ='') OR 
    `allowed` LIKE '%US%'
) AND approved=1;

它的运行时间约为0.02秒。有关如何优化它的任何建议?谢谢。

2 个答案:

答案 0 :(得分:0)

执行速度相同,因为OR和非左锚定的LIKE子句不能正确使用索引。您在US FR等字段中的表格设计不好,应该在您加入的另一个表格中。如果您坚持使用您的设计并且表格很大,则为supplier_id OR子句创建派生表,然后针对同一个表JOIN以查找其余匹配项。这可能还需要一个UNION,因为你有其他的OR。有关更多信息:

http://dev.mysql.com/doc/refman/5.6/en/index-btree-hash.html

答案 1 :(得分:-1)

我设法按如下方式优化它:

SELECT DISTINCT supplier_id FROM products WHERE ((`blocked` NOT LIKE '%US%' AND 
`allowed` ='') OR `allowed` LIKE '%US%') AND approved=1 AND supplier_id IN (1207077, 
1207087, 1207079, 1207082, 1207083, 1207086, 1207084, 1207078, 1207085, 1207094, 
1207097, 1207095, 1207089, 1207091);

现在运行时间为0.0004秒。

感谢winmutt指出我正确的方向: - )