Mysql Slooow垃圾收集查询

Mysql Slooow垃圾收集查询,mysql,performance,Mysql,Performance,我有两个表,一个存储用户会话,另一个存储购物车数据会话有一个购物车id列,该列与购物车表中相应的id相匹配。我正在尝试对基于数据库的会话运行垃圾收集。首先,我删除过期的会话: DELETE FROM sessions WHERE expires < NOW(); 最后一个查询真的很慢,好像超过60秒 我试过这个: DELETE `cart` FROM `cart` WHERE `cart`.`id` NOT IN (SELECT `cart_id` FROM `sessions`) 这

我有两个表,一个存储用户会话,另一个存储购物车数据<代码>会话有一个购物车id列,该列与
购物车
表中相应的
id
相匹配。我正在尝试对基于数据库的会话运行垃圾收集。首先,我删除过期的会话:

DELETE FROM sessions WHERE expires < NOW();
最后一个查询真的很慢,好像超过60秒

我试过这个:

DELETE `cart`
FROM `cart`
WHERE `cart`.`id` NOT IN (SELECT `cart_id` FROM `sessions`)

这也很慢。有任何指针吗?

请确保您的sessions.expires和sessions.cart\u id列已编制索引

如果您有一个高流量站点,并且正在添加大量Cart/sessions,那么由于并发性,您的删除操作将变慢

如果您有很多会话,那么您发布的最后一个操作将总是非常慢(最后需要逐个比较每个id。)


使用IN语句时的经验法则:IN值计数应该相对较小。

确保sessions.expires和sessions.cart\u id列都已编制索引

如果您有一个高流量站点,并且正在添加大量Cart/sessions,那么由于并发性,您的删除操作将变慢

如果您有很多会话,那么您发布的最后一个操作将总是非常慢(最后需要逐个比较每个id。)


使用IN语句时的一条经验法则:IN值计数应该相对较小。

您可以改变它。让每个购物车通过a引用一个会话id,并在删除级联上设置
。这样,当您在会话中删除一行时,与之关联的Cart也会被删除

CREATE TABLE session (session_id INT NOT NULL,
                      expires DATE NOT NULL,
                     PRIMARY KEY (session_id),
                     INDEX expires_index (expires)
) ENGINE=INNODB;                          

CREATE TABLE cart (id INT, 
                   session_id INT,
                   INDEX session_index (session_id),
                   FOREIGN KEY (session_id) REFERENCES session(session_id) ON DELETE CASCADE
) ENGINE=INNODB;
如果您发现删除所有过期的购物车花费的时间太长请使用限制更频繁地执行较小的删除

DELETE FROM session WHERE expires < NOW() ORDER BY expires LIMIT 10;
DELETE FROM session WHERE expires
你可以扭转局面。让每个购物车通过a引用一个会话id,并在删除级联上设置
。这样,当您在会话中删除一行时,与之关联的Cart也会被删除

CREATE TABLE session (session_id INT NOT NULL,
                      expires DATE NOT NULL,
                     PRIMARY KEY (session_id),
                     INDEX expires_index (expires)
) ENGINE=INNODB;                          

CREATE TABLE cart (id INT, 
                   session_id INT,
                   INDEX session_index (session_id),
                   FOREIGN KEY (session_id) REFERENCES session(session_id) ON DELETE CASCADE
) ENGINE=INNODB;
如果您发现删除所有过期的购物车花费的时间太长请使用限制更频繁地执行较小的删除

DELETE FROM session WHERE expires < NOW() ORDER BY expires LIMIT 10;
DELETE FROM session WHERE expires
您是否有
会话的索引。购物车id
?我没有索引。那可能是我的问题吧?不好意思退后阅读索引手册您肯定需要(经常)用于联接的列的索引。您是否有
会话的索引。购物车id
?我没有索引。那可能是我的问题吧?不好意思退后阅读索引手册你肯定需要(经常)用于连接的列的索引。他的查询很好。为什么你不这么认为呢?MySQL删除查询规范(
delete[LOW_PRIORITY][QUICK][IGNORE]FROM tbl_name
…)没有在FROM语句之前列出表名。哦,我糟糕的ypercube,刚才看到我没有在回答中指定我引用的查询。你读过(在你提供的链接上)第二个版本吗,标记了多表语法?我发现它不适用于这种语法,这篇参考文章他的查询很好。为什么你不这么认为呢?MySQL删除查询规范(
delete[LOW_PRIORITY][QUICK][IGNORE]FROM tbl_name
…)没有在FROM语句之前列出表名。哦,我糟糕的ypercube,刚才看到我没有在回答中指定我引用的查询。你读过(在你提供的链接上)第二个版本吗,标记了多表语法?我发现它不适用于此语法和此参考文章