表:
CREATE TABLE IF NOT EXISTS `posts` (
`post_n` int(10) NOT NULL auto_increment,
`id` int(10) default NULL,
`date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`post_n`,`visibility`),
KEY `id` (`id`),
KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `subscriptions` (
`subscription_n` int(10) NOT NULL auto_increment,
`id` int(10) NOT NULL,
`subscribe_id` int(10) NOT NULL,
PRIMARY KEY (`subscription_n`),
KEY `id` (`id`),
KEY `subscribe_id` (`subscribe_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
查询:
SELECT posts.* FROM posts, subscriptions
WHERE posts.id=subscriptions.subscribe_id AND subscriptions.id=1
ORDER BY date DESC LIMIT 0, 15
它很慢,因为使用索引“id”,“subscribe_id”而不是索引“date”,因此排序非常慢。
是否有任何选项可以更改查询,索引和架构?
答案 0 :(得分:1)
可能的改进:
首先,如果您为字段命名而不是使用SELECT帖子,则每个查询将获得几微秒。*会导致架构查找。将您的查询更改为:
SELECT posts.post_n, posts.id, posts.date
FROM posts, subscriptions
WHERE posts.id=subscriptions.subscribe_id
AND subscriptions.id=1
ORDER BY date DESC
LIMIT 0, 15
接下来,这需要MySQL 5.1或更高版本,但您可能需要考虑对表进行分区。您可以考虑两个表的KEY分区。
这应该让你开始。 http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html
E.g。
SET SQL_MODE = 'ANSI';
-- to allow default date
CREATE TABLE IF NOT EXISTS `posts` (
`post_n` int(10) NOT NULL auto_increment,
`id` int(10) default NULL,
`date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`post_n`,`id`),
KEY `id` (`id`),
KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin
PARTITION BY KEY(id) PARTITIONS 32;
--
CREATE TABLE IF NOT EXISTS `subscriptions` (
`subscription_n` int(10) NOT NULL auto_increment,
`id` int(10) NOT NULL,
`subscribe_id` int(10) NOT NULL,
PRIMARY KEY (`subscription_n`,`subscribe_id`),
KEY `id` (`id`),
KEY `subscribe_id` (`subscribe_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin
PARTITION BY KEY(subscribe_id) PARTITIONS 32;
我不得不稍微调整你的主键。所以,请注意,这可能不适合您。请测试并确认。我希望,尽管如此。确保对旧的和新的结构/查询运行sysbench,以便在开始生产之前比较结果。 : - )
答案 1 :(得分:0)
如果您能够修改表格,则可以添加包含ID和日期的多字段索引。 (或修改其中一个现有密钥以包含它们)。
如果您无法对数据库进行更改,并且您知道结果集很小,则可以强制它使用USE KEY(name)
的特定命名密钥。然后在事实之后完成排序,就在返回的reslts上。
希望有所帮助。