【发布时间】:2013-05-05 19:30:31
【问题描述】:
有一个表 users,其主键为 user_id,索引列称为已验证。 另一个表 user_profile 的 PK 为 profile_id,FK 为 user_id 并有一个列 - 名称
现在,我需要找到所有经过验证的用户及其姓名。所以我需要在 user_id 上加入这两个表 -
查询变成 -
select p.name from user_profile p inner join user u on p.user_id = u.user_id
where u.verified = 1;
profile 表中有 700000 条记录,user 表中有相同数量的记录。上面的这个查询需要 13 秒才能运行。请告诉我,如何优化运行时间。
MySQL 5.5 版,YII
编辑
CREATE TABLE IF NOT EXISTS `tbl_profile` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`regyear` int(4) DEFAULT NULL,
`firstname` varchar(128) NOT NULL,
`gender` varchar(10) NOT NULL,
`occupation` int(5) NOT NULL,
`street` varchar(255) DEFAULT NULL,
`state` int(10) DEFAULT NULL,
`city` int(10) DEFAULT NULL,
`zip` int(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `state` (`state`),
KEY `firstname` (`firstname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=626494 ;
--
-- 表tbl_user的表结构
CREATE TABLE IF NOT EXISTS `tbl_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
`password` varchar(128) NOT NULL,
`createtime` int(10) NOT NULL DEFAULT '0',
`lastvisit` int(10) NOT NULL DEFAULT '0',
`status` int(1) NOT NULL DEFAULT '0',
`verified` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
KEY `status` (`status`),
KEY `verified` (`verified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=626494 ;
EXPLAIN SELECT 的输出 - 我编写了与上面相同的查询,但将 999 替换为 1 并使用列状态而不是已验证,这相当于问题陈述。
EXPLAIN SELECT p.firstname
FROM tbl_profile p
INNER JOIN tbl_user u ON p.user_id = u.id
WHERE u.status =999
+----+-------------+-------+------+----------------+---------+---------+-------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------+---------+---------+-------------+--------+-------------+
| 1 | SIMPLE | u | ref | PRIMARY,status | status | 4 | const | 313333 | Using index |
| 1 | SIMPLE | p | ref | user_id | user_id | 4 | newone.u.id | 1 | |
+----+-------------+-------+------+----------------+---------+---------+-------------+--------+-------------+
【问题讨论】:
-
您在表上有哪些索引?添加2个表的
CREATE TABLE语句和EXPLAIN SELECT ...的输出 -
一个用户可以有很多个人资料吗?
-
不,一个用户只有 1 个个人资料,我想您会建议加入他们并制作 1 个表格?实际上用户表仅用于登录,另一个表有个人资料相关数据。
-
不,我已将我的建议添加为答案。不知道 Yii 是否会对这种变化有任何问题。一些 ORM/框架在没有自动递增 PK 的情况下存在表问题。