MySQL在多对多表中按优化排序
表: 查询:MySQL在多对多表中按优化排序,mysql,query-optimization,Mysql,Query Optimization,表: 查询: 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` (
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;
因为使用了索引“id”、“subscribe\u id”而不是索引“date”,所以排序非常慢
是否有任何选项可以更改查询、索引、体系结构?如果您能够修改表,则可以添加包含ID和日期的多字段索引。(或修改其中一个现有键以同时包含这两个键) 如果无法对数据库进行更改,并且知道结果集将变小,则可以使用
use key(name)
强制它使用特定的命名键。然后,就在返回的reslts上,在事件发生后进行排序
希望能有所帮助。可能的改进:
首先,如果您命名字段而不是使用SELECT POST.*这会导致架构查找,那么每个查询将获得几微秒的时间。将查询更改为:
SELECT posts.* FROM posts, subscriptions
WHERE posts.id=subscriptions.subscribe_id AND subscriptions.id=1
ORDER BY date DESC LIMIT 0, 15
接下来,这需要MySQL 5.1或更高,但您可能需要考虑对表进行分区。您可以考虑两个表的关键分区。 这应该让你开始。
例如 我不得不稍微调整一下你的主键。所以,小心,这可能不适合你。请测试并确认。不过,我希望这样做。在投入生产之前,确保针对新旧结构/查询运行sysbench,以比较结果。:-)我照你说的做了,但没有效果。速度仍为0.1,无需订购0.0013。我很绝望哦,是的,这对我来说是件新鲜事。我会更新mysql版本并进行测试,谢谢!:)在添加分区后,2的速度提高了,这很好。我需要对它进行更多的测试,而不是X。它总是会抛出所有分区,但如果我按日期在desc中排序,那么我只需要最后15个分区,总是,可能存在另一种分区方式,你知道吗?对不起,我说的是英语。你可以按日期来划分。阅读文档,看看它是否对您正在尝试的内容有意义;或者按范围(年(日期))(分区p1值小于(2010),分区p2值小于(2011))更改表posts分区,但如果执行简单查询:选择*FROM
posts
WHERE year(日期)=2009,则显示扫描的所有分区不是一个。我做错了什么?
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
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;