我已经使用SQL多年了,但很少有更简单的插入和选择等...所以我不是SQL专家.我想知道我是否可以帮助优化我在SQLite上执行的更复杂的SQL语句,从PHP到PDO.
声明似乎工作正常,似乎需要更长的时间,我预期(或者我可能只是期望太多).
这是SQL:
INSERT OR IGNORE INTO MailQueue(SubscriberID, TemplateID) SELECT Subscribers.ID, '1' AS TemplateID FROM Subscribers INNER JOIN SubscriberGroups ON Subscribers.ID=SubscriberGroups.SubscriberID WHERE SubscriberGroups.GroupID IN ('1', '2', '3') AND Subscribers.ID NOT IN ( SELECT Subscribers.ID FROM Subscribers INNER JOIN SubscriberGroups ON Subscribers.ID=SubscriberGroups.SubscriberID WHERE SubscriberGroups.GroupID IN ('4', '5', '6') );
我得到的是一个或多个组中的订阅者列表.我想将订阅者添加到邮件队列中,选择属于一个或多个组(1,2,3)的订阅者,但排除那些也在另一组组中的订阅者(4,5,6).
首先,是上面的SQL典型的如何做到这一点?
其次,我应该有什么指标尽可能有效地完成这项工作?
目前,在平均规格LAMP上通过大约5000个订户记录(以及少数几个组)需要大约30秒.
在一天结束时,表现并不是那么重要,但我想更好地理解这些东西,所以任何见解都非常受欢迎.
布拉德
可能是额外的联接正在杀死你.如果你做了怎么办:
SELECT Subscribers.ID, '1' AS TemplateID FROM Subscribers WHERE EXISTS( SELECT * FROM SubscriberGroups WHERE Subscribers.ID=SubscriberGroups.SubscriberID AND SubscriberGroups.GroupID IN ('1', '2', '3') ) AND NOT EXISTS( SELECT * FROM SubscriberGroups WHERE Subscribers.ID=SubscriberGroups.SubscriberID AND SubscriberGroups.GroupID IN ('4', '5', '6') );
您还需要确保在SubscriberGroups(SubscriberID,GroupID)上有索引
我的猜测是订阅者已经拥有ID索引,对吧?
编辑:另一种选择,可能会或可能不会更快.看看每个查询计划看看......
这可能是单个索引扫描,可能比两个索引搜索更快,但它取决于SQLite的优化器......
SELECT Subscribers.ID, '1' AS TemplateID FROM Subscribers INNER JOIN( SELECT SUM( CASE WHEN GroupID IN('1', '2', '3') THEN 1 ELSE 0 END ) AS inGroup, SUM( CASE WHEN GroupID IN('4', '5', '6') THEN 1 ELSE 0 END ) AS outGroup, SubscriberID FROM SubscriberGroups WHERE SubscriberGroups.GroupID IN ('1', '2', '3', '4', '5', '6' ) ) SubscriberGroups ON Subscribers.ID=SubscriberGroups.SubscriberID AND inGroup > 0 AND outGroup = 0