你好stackoverflow我这里有一个sql语句,它是相当缓慢的执行,我认为这是由于在下面的sql中看到的子查询。我的问题是简单地给出了这个子查询和事实,它必须设置'exists'为0或1给定的逻辑可以改善这一点。
SELECT
p.id,
p.name,
(
SELECT
COUNT(*) > 0
FROM
product_log AS pl
WHERE
pl.product_id = p.id
AND
pl.state_name in ("Creation", "Auction", ...)
) AS 'has_log'
from product as p;
为日志和产品创建表
CREATE TABLE `product_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) DEFAULT NULL,
`state_name` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`create_datetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `product_id` (`product_id`),
KEY `state_name` (`state_name`,`create_datetime`)
(`id`,`product_id`,`state_name`,`create_datetime`)
) ENGINE=InnoDB AUTO_INCREMENT=8132540 DEFAULT CHARSET=utf8;
在查询上运行explain有点不同,因为与实际运行的查询相比,省略了许多详细信息,但输出如下
|id |select_type |table|partitions|type |possible_keys |key |key_len|ref |rows |filtered|Extra |
|---|------------------|-----|----------|------|-----------------------------------------------------------------|-------------------|-------|-----------------------------|------|--------|--------------------------------------------|
|1 |PRIMARY |p | |eq_ref|PRIMARY,guarantee_list_index |PRIMARY |4 |ppd.product_id |1 |100 | |
|2 |DEPENDENT SUBQUERY|pl | |ref |product_id,state_name |product_id |5 |p.id |3 |51.5 |Using where |
2条答案
按热度按时间8yoxcaq71#
像什么?
消除了每行执行的子选择,并且避免使用count(),如果只需要存在,则必须遍历所有记录
hmtdttj42#
您不必计算所有匹配项,只需检查是否至少存在一个与
EXISTS
或IN
匹配的项。或
这两个查询做的是相同的事情,因此DBMS可以为这两个查询提供相同的执行计划。但是查询显示DBMS可以通过两种方式来完成任务:
1.遍历所有产品并查找每个产品的日志。
1.查找具有请求日志的所有产品,并使用此列表进行查找。
这些方法需要不同的索引。如果要查找产品的日志,我需要:
如果我想先建立查阅清单,我想:
我建议您创建两个索引。然后查看查询的解释计划,查看使用了哪一个,并删除另一个。