我有一个表op_log,所有记录计数都是47362198
。并有低于列和索引,
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`operate_result` varchar(100) DEFAULT NULL,
`create_user_id` varchar(128) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`,`create_user_id`),
实际上user_id
为空,仅使用create_user_id
,首先我在sql下面执行
select * from op_log where operate_result like 'foo%' order by id desc limit 10;
......
10 rows in set (0.01 sec)
然后我添加create_user_id
,
select * from op_log where operate_result like 'foo%' and create_user_id = '4987bcbabc7530ee4c777038184d364b' order by id desc limit 10;
非常奇怪它似乎会永远执行,我必须用CTRL + C来阻止它,然后我添加另一个user_id条件(实际上user_id从未使用过,所以它为空)
select * from op_log where operate_result like 'foo%' and create_user_id = '4987bcbabc7530ee4c777038184d364b' and user_id is null order by id desc limit 10;
...
1 row in set (0.01 sec)
那么为什么只有create_user_id
才能永远执行,但要么没有,要么两者都有user_id
可以快速执行?
explain select * from op_log where operate_result like 'foo%' order by id desc limit 10;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | op_log | index | NULL | PRIMARY | 8 | NULL | 10 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
explain select * from op_log where operate_result like 'foo%' and create_user_id = '4987bcbabc7530ee4c777038184d364b' order by id desc limit 10;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | op_log | index | NULL | PRIMARY | 8 | NULL | 10 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
explain select * from op_log where operate_result like 'foo%' and create_user_id = '4987bcbabc7530ee4c777038184d364b' and user_id is null order by id desc limit 10;
+----+-------------+--------+------+---------------+---------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+---------+---------+-------------+------+-------------+
| 1 | SIMPLE | op_log | ref | user_id | user_id | 396 | const,const | 2 | Using where |
+----+-------------+--------+------+---------------+---------+---------+-------------+------+-------------+
答案 0 :(得分:1)
您在该表上的索引
KEY `user_id` (`user_id`,`create_user_id`),
是复合键。如果您在user_id
子句中同时指定create_user_id
和WHERE
的条件,它只会加快速度。
查询
select * from op_log where operate_result like 'foo%'
and create_user_id = '4987bcbabc7530ee4c777038184d364b'
order by id desc limit 10;
无法使用该索引,因为user_id
上没有条件,因此MySQL必须检查所有4700万行。
您要做的是在create_user_id
列上添加索引(键),因为您不关心always-null user_id
:
ALTER TABLE op_log ADD INDEX (create_user_id);
答案 1 :(得分:0)
(肯尼的答案可能是你要找的主要答案。)
<?php
// Start the session
session_start();
?>
<!DOCTYPE html>
<html>
<body>
<?php
// Set session variables
$_SESSION["favcolor"] = "green";
$_SESSION["favanimal"] = "cat";
echo "Session variables are set.";
?>
</body>
</html>
不应该快速,但可能是因为大多数最后(如在select * from op_log where operate_result like 'foo%' order by id desc limit 10;
中)几行满足order by id desc
。如果您将where operate_result like 'foo%'
更改为不太常见的内容,您可能会看到显着减速。