好吧,让我们开箱即用.似乎有两组结果 – 作者有一些这样的书,有些没有.第一种情况通过以下方式更有效地完成:
SELECT author_id,
COUNT(*)+1 AS books_under_fifty
FROM `book`
WHERE `org` = 1
AND `country` = 'USA'
AND publish_date >= '2010-05-01'
AND publish_date < '2010-05-01' + INTERVAL 1 YEAR
AND `price` < 50
这可能是最好的服务
INDEX(country, org, publish_date, price, author_id)
如果你对它的表现感到满意,那么你就可以开箱即用,找到“其他作者”.
回到2范围问题.有时可以通过分区来解决这个问题.不知道数据的分布(一年是总数的一小部分?或价格怎么样?),我不能说哪个更好:
PARTITION BY RANGE(TO_DAYS(publish_date))
由于无法使用DECIMAL,因此按价格进行分区.将价格存储为美分数并使用PARTITION BY RANGE(美分)可行,但笨拙.
然后制作分区键的20-50个分区.这会给你一个’范围’的“分区修剪”,但是那时索引需要为另一个调整.假设您按publish_date进行分区:
INDEX(country, org, price)
PRIMARY KEY(id, publish_date)
同时,……
如果您使用标准country_codes,请不要使用utf8;使用ascii,至少对于该列.
什么是组织区分这本书?还是有一些缺少的列?没有其他“独特”专栏吗?
另一种可能更好的变体:
PRIMARY KEY(country, org, price, -- for clustering
publish_date, -- because partitioning requires it
id) -- to assure uniqueness
INDEX(id)
此变体假设您没有’自然’PK.它会更高效,因为它将所需的行聚集在一起.我没有在PK中包含author_id,因为它在行中很容易获得.
添加索引
ADD INDEX ac(author_id,country)欺骗它使用i0.去搞清楚.注意:我保留了(author_id)完整的索引列表中的第一个;所以它不仅仅是索引的顺序.
我正在使用Percona的5.6.22-71.0-log.
请注意,只有4个不同的国家/地区值,均匀分布.但是有许多不同的author_id,使它本身更具“选择性”.