我正在開發一個基於XenForo引擎的網站,並且在查詢中存在一個問題,該查詢獲取所有線程和連接張貼表和論壇表以獲取第一篇文章和論壇的一些信息線程屬於。查詢看起來像:大量行的MySQL性能問題
SELECT thread . *
FROM xf_thread AS thread
INNER JOIN xf_node AS node ON (node.node_id = thread.node_id)
INNER JOIN xf_post AS post ON (post.post_id = thread.first_post_id)
WHERE thread.node_id IN ('295', '296', '297', '298', '299', '300', '301', '302', '256', '2575', '258', '259', '260', '253', '254', '255', '127', '163', '159', '144', '145', '146', '147', '148', '164', '165', '166', '167', '168', '169', '170', '162', '171', '173', '172', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '151', '152', '153', '154', '155', '157', '156', '158', '161', '160', '149', '227', '232', '237', '233', '236', '234', '235', '238', '248', '240', '241', '242', '239', '246', '247', '243', '244', '245', '228', '229', '230', '231', '249', '250', '251', '174', '190', '195', '199', '193', '191', '197', '198', '192', '200', '204', '207', '205', '203', '206', '202', '208', '201', '187', '176', '177', '178', '189', '188', '180', '186', '184', '185', '182', '183', '181', '179', '209', '211', '217', '218', '219', '210', '212', '213', '214', '215', '216', '220', '222', '223', '224', '221', '225', '261', '291', '276', '272', '270', '265', '277', '267', '286', '292', '289', '274', '264', '287', '278', '282', '279', '281', '280', '283', '284', '285', '290', '275', '268', '263', '266', '294', '262', '293', '269', '273', '288', '271')
ORDER BY thread.last_post_date DESC
LIMIT 10
解釋查詢的結果是:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE node index PRIMARY PRIMARY 4 NULL 199 Using where; Using index; Using temporary; Using filesort 1 SIMPLE thread ref node_id_last_post_date,node_id_sticky_last_post_date node_id_last_post_date 4 node.node_id 221 1 SIMPLE post eq_ref PRIMARY PRIMARY 4 thread.first_post_id 1 Using index
查詢需要9+秒來執行。
刪除加入xf_node表,在0.01秒內運行查詢。解釋貌似
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE thread index node_id_last_post_date,node_id_sticky_last_post_da... last_post_date 4 NULL 69970 Using where 1 SIMPLE post eq_ref PRIMARY PRIMARY 4 thread.first_post_id 1 Using index
刪除xf_post表的連接運行在0.01秒內查詢,解釋貌似
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE thread index node_id_last_post_date,node_id_sticky_last_post_da... last_post_date 4 NULL 70840 Using where 1 SIMPLE node eq_ref PRIMARY PRIMARY 4 thread.node_id 1 Using index
因此,只有當兩個表的連接問題的存在,但聯接本身似乎是完全正確和完全分開工作。
表中的行數 - xf_thread:71855,xf_node:178,xf_post:2977326
我的假設是,當兩個表的連接的MySQL開始使用不正確的索引,並可能迫使指數將解決問題?
您的幫助和建議,以找到一種方法來解決這個問題,高度讚賞。
編輯:下面是CREATE TABLE語句中的所有表涉案
xf_node
CREATE TABLE `xf_node` (
`node_id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(50) NOT NULL,
`description` text NOT NULL,
`node_name` varchar(50) default NULL COMMENT 'Unique column used as string ID by some node types',
`node_type_id` varbinary(25) NOT NULL,
`parent_node_id` int(10) unsigned NOT NULL default '0',
`display_order` int(10) unsigned NOT NULL default '1',
`display_in_list` tinyint(3) unsigned NOT NULL default '1' COMMENT 'If 0, hidden from node list. Still counts for lft/rgt.',
`lft` int(10) unsigned NOT NULL default '0' COMMENT 'Nested set info ''left'' value',
`rgt` int(10) unsigned NOT NULL default '0' COMMENT 'Nested set info ''right'' value',
`depth` int(10) unsigned NOT NULL default '0' COMMENT 'Depth = 0: no parent',
`style_id` int(10) unsigned NOT NULL default '0' COMMENT 'Style override for specific node',
`effective_style_id` int(10) unsigned NOT NULL default '0' COMMENT 'Style override; pushed down tree',
PRIMARY KEY (`node_id`),
UNIQUE KEY `node_name_unique` (`node_name`,`node_type_id`),
KEY `parent_node_id` (`parent_node_id`),
KEY `display_order` (`display_order`),
KEY `display_in_list` (`display_in_list`,`lft`),
KEY `lft` (`lft`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=304 ;
xf_post
CREATE TABLE `xf_post` (
`post_id` int(10) unsigned NOT NULL auto_increment,
`thread_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`username` varchar(50) NOT NULL,
`post_date` int(10) unsigned NOT NULL,
`message` mediumtext NOT NULL,
`ip_id` int(10) unsigned NOT NULL default '0',
`message_state` enum('visible','moderated','deleted') NOT NULL default 'visible',
`attach_count` smallint(5) unsigned NOT NULL default '0',
`position` int(10) unsigned NOT NULL,
`likes` int(10) unsigned NOT NULL default '0',
`like_users` blob NOT NULL,
`warning_id` int(10) unsigned NOT NULL default '0',
`warning_message` varchar(255) NOT NULL default '',
PRIMARY KEY (`post_id`),
KEY `thread_id_post_date` (`thread_id`,`post_date`),
KEY `thread_id_position` (`thread_id`,`position`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3123657 ;
xf_thread
CREATE TABLE `xf_thread` (
`thread_id` int(10) unsigned NOT NULL auto_increment,
`node_id` int(10) unsigned NOT NULL,
`title` varchar(150) NOT NULL,
`reply_count` int(10) unsigned NOT NULL default '0',
`view_count` int(10) unsigned NOT NULL default '0',
`user_id` int(10) unsigned NOT NULL,
`username` varchar(50) NOT NULL,
`post_date` int(10) unsigned NOT NULL,
`sticky` tinyint(3) unsigned NOT NULL default '0',
`discussion_state` enum('visible','moderated','deleted') NOT NULL default 'visible',
`discussion_open` tinyint(3) unsigned NOT NULL default '1',
`discussion_type` varchar(25) NOT NULL default '',
`first_post_id` int(10) unsigned NOT NULL,
`first_post_likes` int(10) unsigned NOT NULL default '0',
`last_post_date` int(10) unsigned NOT NULL,
`last_post_id` int(10) unsigned NOT NULL,
`last_post_user_id` int(10) unsigned NOT NULL,
`last_post_username` varchar(50) NOT NULL,
`prefix_id` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`thread_id`),
KEY `node_id_last_post_date` (`node_id`,`last_post_date`),
KEY `node_id_sticky_last_post_date` (`node_id`,`sticky`,`last_post_date`),
KEY `last_post_date` (`last_post_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=76301 ;
謝謝。
你可以做它的兩個查詢。首先獲取'thred'與'post'連接並在第二個'select * from xf_node WHERE node_id IN(從第一個查詢中節點列表)' – piotrekkr
這個問題似乎更適合[dba.se]。投票遷移它。 –
@piotrekkr這個查詢是由XenForo使用它的模型生成的,所以拆分成單獨的查詢不是我的選擇 –