2

我想为字母表中的每个字母创建一个包含几个结果的索引页面。

目前我有这个:

SELECT url_slug, name FROM artists WHERE name LIKE "A%" ORDER BY rand() LIMIT 10 
SELECT url_slug, name FROM artists WHERE name LIKE "B%" ORDER BY rand() LIMIT 10 
SELECT url_slug, name FROM artists WHERE name LIKE "C%" ORDER BY rand() LIMIT 10 
SELECT url_slug, name FROM artists WHERE name LIKE "D%" ORDER BY rand() LIMIT 10 
SELECT url_slug, name FROM artists WHERE name LIKE "E%" ORDER BY rand() LIMIT 10 
SELECT url_slug, name FROM artists WHERE name LIKE "F%" ORDER BY rand() LIMIT 10 

是否有另一种性能更友好的方法来实现这一目标?

Ps 我知道'order by rand()' 不是很好。但这只是在开发中。

4

4 回答 4

2

出于您要达到的目的,该查询不会比该 IMO 更好。但是,如果表是巨大的,如果可能想要偶尔缓存表,单独保存一个固定字母的值。

并且索引,索引您的记录,根据字段。

于 2012-04-10T23:54:43.697 回答
1

试一试,它对我的​​测试数据有效:

SELECT url_slug, name FROM artists WHERE name REGEXP '^[A-Z]';

--更新--

我得到一个查询,它将提取所有名称(无限制)并按字母分组,但没有限制,可能不值得。

# Note, you do not need the WHERE clause if you want all letters
# I left it in for dev testing
select GROUP_CONCAT(CONCAT(url_slug, ':', name)) AS list, substr(name, 1, 1) as letter from artists where name REGEXP '^[A-B]' group by letter;

您可以做的是每隔几个小时发出一次这样的查询,并按字母缓存结果。不过我同意你的观点,我认为最好查询一次,而不是查询 26 次,只要你不为每个查询都提取一个巨大的结果集,我认为填充缓存是可以的。

于 2012-04-10T23:53:52.400 回答
0

我不是你所说的每个字母的“几个结果”的意思,但你是否有可能做这样的事情:

select left(name, 1), url_slug, group_concat(name) 
from artists 
group by left(name, 1);

这让你每个字母都能找到所有的艺术家。

于 2012-04-10T23:54:46.853 回答
0

表现不佳(26K 记录在我的上网本上需要 0.04 秒),但比您的 26 个查询有趣且略快 -

SELECT
    url_slug, name,
    IF( @prev <> LEFT(name, 1), @rownum := 1, @rownum := @rownum+1 ) AS rank,
    @prev := LEFT(name, 1)
FROM(
    SELECT * FROM artists ORDER BY LEFT(name, 1), RAND()
) tmp, (SELECT @rownum := NULL, @prev := '') init
HAVING rank <= 2
于 2012-04-11T00:58:09.590 回答