这是我正在使用的当前查询,它到目前为止做得很好:
SELECT a.*
FROM ads AS a
WHERE id = (
SELECT id
FROM ads AS b
WHERE a.zone_name=b.zone_name
AND publish_date <= CURDATE() AND expire_date >= CURDATE() AND active = 1
LIMIT 1
)
每个现有区域返回一个广告,然后在按区域排序后,在模板中的相应位置显示相应的广告。
现在我们已经引入了响应式布局,因此区域不能始终适合广告的相同维度,我希望始终获取最适合的广告。我首先使用Javascript阅读浏览器分辨率,然后将其传回PHP,然后PHP和MySQL可以决定适合哪些广告。
但我不知道如何比我在下面提供的解决方案更容易适应查询条件,我想要一个更好的解决方案。由于不同的区域将在相同的分辨率上适应不同的尺寸,我需要一种方法来指定每个区域的大小,我能想到的唯一方法是逐个获取它们,为每个区域指定所需的大小,然后对它们进行UNION ALL
。
但执行起来似乎相当缓慢,我想知道是否有一个更好的可以简化条件并可能消除publish_date
条件的重复,避免UNION
因此(希望)执行得更快?
(SELECT ads.* FROM ads WHERE zone_name = 'b' AND width=468 AND publish_date <= CURDATE() AND expire_date >= CURDATE() AND active = 1 LIMIT 1)
UNION ALL
(SELECT ads.* FROM ads WHERE zone_name = 'a1' AND width=728 AND publish_date <= CURDATE() AND expire_date >= CURDATE() AND active = 1 LIMIT 1)
...
答案 0 :(得分:1)
这是您的查询:
SELECT a.*
FROM ads a
WHERE id = (SELECT id
FROM ads b
WHERE a.zone_name=b.zone_name AND
publish_date <= CURDATE() AND
expire_date >= CURDATE() AND
active = 1
LIMIT 1
);
您似乎并不关心您获得哪些广告(例如获取最新广告)。
开始表现的好地方是一个指数:
create index idx_ads_4 on ads(zone_name, active, expire_date, publish_date)
这是一个&#34;覆盖索引&#34;,这意味着子查询中使用的所有列都使用索引。
接下来,如果区域的大小不同,则将其放入表中并使用join
。完整查询类似于:
select a.*
from (select 'b' as zone_name, 468 as width union all
select 'a1', 728
) ZoneWidths join
ads a
on a.zone_name = zonewidths.zone_name and a.width = zonewidths.width
where id = (SELECT id
FROM ads b
WHERE a.zone_name=b.zone_name AND
a.width = b.width AND
publish_date <= CURDATE() AND
expire_date >= CURDATE() AND
active = 1
LIMIT 1
);
此查询的相应索引还需要width
:
create index idx_ads_5 on ads(zone_name, width, active, expire_date, publish_date)