1

查询的一部分是:

SELECT * FROM `o` WHERE ....
AND `id` IN     (SELECT DISTINCT `id` FROM `o` WHERE `activity` = '1' AND `date` < '20130310'                      ORDER BY `id` ASC)
AND `id` NOT IN (SELECT DISTINCT `id` FROM `o` WHERE `activity` = '1' AND `date` BETWEEN '20130310' AND '20130329' ORDER BY `id` ASC)
....

描述:在20130310之前有活动并且在 20130310 和 20130329 之间没有活动的ID

1)我可以加速这个mysql查询吗?

2) 是否有助于提高和ORDER BY的速度?INNOT IN

4

3 回答 3

2

由于 MySQL 中的 IN() 子查询通常很慢(至少在 5.6 之前),因此您最好使用 join

SELECT * FROM `o`
LEFT JOIN
(SELECT `id` AS `idactive` FROM `o` WHERE `activity` = '1' AND `date` BETWEEN '20130310' AND '20130329') as t
USING `id`
WHERE `activity` = '1' AND `date` < '20130310' AND `idactive` IS NULL
于 2013-06-26T13:38:20.927 回答
0

如果id是您的主键(应该是),那么您的两个与日期相关的子句之一是无用的(`date` < '20130310'总是暗示NOT (`date` BETWEEN '20130310' AND '20130329'),允许您将事情简化为:

select *
from o
where activity = 1
and date < '20130310'

如果id实际上是其他字段中的一个(在这种情况下,这是一个非常令人困惑的名称选择),它在 1-n 或 nm 关系中引用了一个单独的表,我假设您正在寻找至少一个在该日期范围内有活动,但此后没有新活动。在这种情况下,您的查询可以简化为:

SELECT * FROM `o` WHERE ....
AND `id` IN     (SELECT `id` FROM `o` WHERE `activity` = '1' AND `date` < '20130310')
AND `id` NOT IN (SELECT `id` FROM `o` WHERE `activity` = '1' AND `date` BETWEEN '20130310' AND '20130329')

换句话说,thedistinctorder by从句都是没有意义的。

在任何一种情况下,如果相关,还请注意您的date字段应该是 type date,而不是 type varchar

于 2013-06-26T12:53:43.790 回答
0

你可以那样做

  SELECT * FROM `o` WHERE ....
  AND `id` IN     (SELECT DISTINCT `id` FROM `o` 
                   WHERE `activity` = '1' AND `date` < '20130310'   
                   ORDER BY `id` ASC)

你不需要第二个 AND 因为你已经选择了date < 20130310所以它不会选择20130311 20130312......20130329

或者您可以简单地执行此查询

    SELECT * FROM `o` WHERE ....
    AND `activity` = '1' AND `date` < '20130310'   
    GROUP BY `id` 
    ORDER BY `id` ASC
于 2013-06-26T12:42:58.577 回答