我看到我的查询进行了全表扫描,并且花费了大量时间。我听说建立索引可以加快速度,并且我在表中添加了一些索引。我还应该创建其他索引来使查询速度更快吗?
我的查询是:
SELECT p.id, n.people_type_id, n.full_name, n.post, p.nick,
p.key_name, p.email, p.internal_user_id FROM email_routing e
JOIN people_emails p ON p.id=e.receiver_email_id
JOIN people n ON n.id = p.people_id
WHERE e.message_id = 897360 AND e.basket=1
这是解释结果:
EXPLAIN SELECT p.id, n.people_type_id, n.full_name, n.post, p.nick, p.key_name, p.email, p.internal_user_id FROM email_routing e JOIN people_emails p ON p.id=e.receiver_email_id JOIN people n ON n.id = p.people_id WHERE e.message_id = 897360 AND e.basket=1
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE n NULL ALL PRIMARY NULL NULL NULL 1 100.00 NULL
1 SIMPLE p NULL ALL PRIMARY NULL NULL NULL 3178 10.00 Using where; Using join buffer (Block Nested Loop)
1 SIMPLE e NULL ref bk1 bk1 4 server.p.id 440 1.00 Using where; Using
这是表格strucutre:
SHOW CREATE TABLE people_emails;
CREATE TABLE `people_emails` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nick` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`key_name` varchar(255) NOT NULL,
`people_id` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '0',
`activity` int(11) NOT NULL,
`internal_user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `email` (`email`)
) ENGINE=MyISAM AUTO_INCREMENT=22114 DEFAULT CHARSET=utf8
SHOW CREATE TABLE email_routing;
CREATE TABLE `email_routing` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message_id` int(11) NOT NULL,
`sender_email_id` int(11) NOT NULL,
`receiver_email_id` int(11) NOT NULL,
`basket` int(11) NOT NULL,
`status` int(11) NOT NULL,
`popup` int(11) NOT NULL DEFAULT '0',
`tm` int(11) NOT NULL DEFAULT '0',
KEY `id` (`id`),
KEY `bk1` (`receiver_email_id`,`status`,`sender_email_id`,`message_id`,`basket`),
KEY `bk2` (`sender_email_id`,`tm`)
) ENGINE=InnoDB AUTO_INCREMENT=1054618 DEFAULT CHARSET=utf8
SHOW CREATE TABLE people;
CREATE TABLE `people` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fname` varchar(255) CHARACTER SET cp1251 NOT NULL,
`lname` varchar(255) CHARACTER SET cp1251 NOT NULL,
`patronymic` varchar(255) CHARACTER SET cp1251 NOT NULL,
`gender` tinyint(1) NOT NULL,
`full_name` varchar(255) NOT NULL DEFAULT ' ',
`category` int(11) NOT NULL,
`people_type_id` int(255) DEFAULT NULL,
`tags` varchar(255) CHARACTER SET cp1251 NOT NULL,
`job` varchar(255) CHARACTER SET cp1251 NOT NULL,
`post` varchar(255) CHARACTER SET cp1251 NOT NULL,
`profession` varchar(255) CHARACTER SET cp1251 DEFAULT NULL,
`zip` varchar(16) CHARACTER SET cp1251 NOT NULL,
`country` int(11) DEFAULT NULL,
`region` varchar(10) NOT NULL,
`city` varchar(255) CHARACTER SET cp1251 NOT NULL,
`address` varchar(255) CHARACTER SET cp1251 NOT NULL,
`address_date` date DEFAULT NULL,
`inner` tinyint(4) NOT NULL,
`contact_through` varchar(255) DEFAULT '',
`next_call` date NOT NULL,
`additional` text CHARACTER SET cp1251 NOT NULL,
`user_id` int(11) NOT NULL,
`changed` datetime NOT NULL,
`status` int(11) DEFAULT NULL,
`nick` varchar(255) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`last_update_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`area` text NOT NULL,
`reviewed_` tinyint(4) NOT NULL,
`phones_old` text NOT NULL,
`post_sticker` text NOT NULL,
`permissions` int(120) NOT NULL DEFAULT '0',
`internal_user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `most_used` (`category`,`status`,`city`,`lname`,`next_call`),
KEY `registrars` (`category`,`status`,`contact_through`,`next_call`),
FULLTEXT KEY `lname` (`lname`),
FULLTEXT KEY `fname` (`fname`),
FULLTEXT KEY `mname` (`patronymic`),
FULLTEXT KEY `Full Name` (`full_name`)
) ENGINE=MyISAM AUTO_INCREMENT=415009 DEFAULT CHARSET=utf8
如何选择用于建立索引的列,我是否也应该选择文本columnts或仅适用于numer columnts
答案 0 :(得分:1)
表 email_routing 似乎有1054618行。
然后您尝试通过message_id查找一行。
e.message_id = 897360
BUT message_id必须建立索引以加快查询速度。
message_id 是索引bk1
的一部分,但这还不够,因为 message_id 不是索引的第一列。
答案 1 :(得分:0)
email_routing
的需求
INDEX ( message_id, basket, -- first, in either order
receiver_email_id ) -- for "covering"
您的bk1
以receiver_email_id
开始;这不是差。
WHERE
中包括经过=
测试的列。WHERE
,GROUP BY
和ORDER BY
中的其他列(在您的情况下为无);顺序很重要,但不在此讨论范围之内。TEXT
(不能在索引中),请不要打扰。然后移至其他表。在两个JOINs
中,似乎它们会被PRIMARY KEYs
(JOIN x ON x.id = ...
)击中
更多讨论:Cookbook for creating indexes
关于其他问题...
您确实应该移至InnoDB。从5.6开始,它包括FULLTEXT
,但是有一些differences。特别是,您可能需要更多的全文索引。例如,MATCH(lname, fname)
需要FULLTEXT(lname, fname)
。
您真的要坚持使用cp1251
吗?它将您的内部化主要限制为英语,俄语,保加利亚语,塞尔维亚语和马其顿语。尚不清楚FULLTEXT
(MyISAM或InnoDB)与那些非英语语言的配合效果如何。
INTs
始终为4个字节;考虑使用较小的版本。
真的只有一个people
吗?优化器认为这是最好的表,但事实并非如此。我希望我在email_routing
上改进的索引能使它从该表开始-绝对是最佳选择。