Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 优化这个查询,从一个有500.000个用户和一个条件的MySQL数据库中检索用户_Php_Mysql_Performance_Optimization - Fatal编程技术网

Php 优化这个查询,从一个有500.000个用户和一个条件的MySQL数据库中检索用户

Php 优化这个查询,从一个有500.000个用户和一个条件的MySQL数据库中检索用户,php,mysql,performance,optimization,Php,Mysql,Performance,Optimization,Suposse I拥有下一个包含500.000行的MySQL数据库: 我需要得到最后20个未经验证的用户,因此我使用下一个查询: SELECT * FROM users WHERE verified != 1 ORDER BY id DESC LIMIT 20 但这需要1.2秒才能完成 我如何优化它?或者在php中以其他方式获得相同的结果 [编辑] ID是主索引,VERIFIED也是索引 [编辑2] [编辑3] 是 以及查询的配置文件: Status Duration (initializa

Suposse I拥有下一个包含500.000行的MySQL数据库:

我需要得到最后20个未经验证的用户,因此我使用下一个查询:

SELECT * FROM users WHERE verified != 1 ORDER BY id DESC LIMIT 20
但这需要1.2秒才能完成

我如何优化它?或者在php中以其他方式获得相同的结果

[编辑]

ID是主索引,VERIFIED也是索引

[编辑2]

[编辑3]

以及查询的配置文件:

Status  Duration
(initialization)    0.0000307
Opening tables  0.000003
System lock 0.0000017
Table lock  0.0000042
init    0.000017
optimizing  0.0000077
statistics  0.000097
preparing   0.000054
executing   0.0000007
Sorting result  1.2321507
Sending data    0.000272
end 0.000004
query end   0.0000025
freeing items   0.0000099
closing tables  0.0000025
logging slow query  0.0000005
在“已验证”上添加索引,并改用以下查询:

SELECT * FROM users WHERE verified = 0 ORDER BY id DESC LIMIT 20
假设“已验证”可以是0或1


如果使用instead of=MySQL,将忽略索引并执行完整表扫描,从而显著降低查询速度。

添加新索引:{verified,id}。否则,您将不得不进行全表扫描。

编辑:对结果进行排序时,您的查询速度很慢-如果给定的顺序不正确,这可能是由索引造成的。MySQL默认为ASC排序顺序

请参阅mysql手册:

请查看以下链接:

您可能需要优化索引:

OPTIMIZE TABLE users;
将id和verified结合在一起可能是有意义的


您有很多索引-这可能会混淆mysql。

创建另一个没有经过验证的用户的表。这是我想要使用的最后一个解决方案。

您需要一个包含id和电子邮件验证的索引

然后解释从验证电子邮件的用户处选择id!=1按id描述的订单限制20份打印


特别是使用速度慢的文件排序已经消失了。

就像quantumSoup的答案一样,而是在验证id上设置一个索引,假设您假设id永远在增加

SELECT * FROM users WHERE verified = 0 ORDER BY id DESC LIMIT 20
我还假设verified仅为0,1


不要使用索引,因为它会破坏索引。将verified放在索引中的第一位,以便它可以进行简单的范围扫描。

如果verified的可能值仅为0和1,请在上创建索引

(verified, id)
并重写您的查询:

SELECT  *
FROM    users
WHERE   verified = 0
ORDER BY
        id DESC
LIMIT 20

此解决方案使用单个索引进行筛选和排序,无论您的数据分布如何,都能正常工作。

这需要0秒的计算时间。你确定你的索引已验证,而不是id已验证吗?@Johan:id上有主键,verified上有一个简单的键,时间更长的东西已验证!=1您可以将查询包装在解释中并发布结果吗?如前所述-请让mysql解释它的查询计划,并请提供有关索引类型和您使用InnoDB、MyISAM等存储引擎的更多信息。@Mike B:可能的\u键:已验证,键\u len:2,ref:null,行:345195,额外:使用where;使用filesort——我也分析了它,排序需要1.2秒,占99%的时间。用户有500.000行。无论他是否保留操作员,它都将执行完整的表扫描。这是一个有效的解决方案,但我第一次还不明白这一点。Thank.OPTIMIZE不起作用,所以验证索引的基数是2Ah,因为我使用了所有的索引,所以有很多索引。相同的结果为=0,1.2秒。这是一个亚秒级的查询:为什么会起作用?这个有两列的索引是如何工作的?啊,只有当你删除了之前的电子邮件验证索引时,这个索引才会工作。这很吸引人。但完全违背了我关于指数如何工作的直觉。Volker,你能解释一下为什么两个单独的索引没有成功吗?nicolas78:不,我放弃了去理解索引合并在MySQL中什么时候起作用,为什么不起作用。但请看一下:和@VolkerK:index_intersect可以将非PK字段与=谓词组合,将PK字段与范围谓词组合。它不适用于ORDER BY ALYST结果文件排序。因为您希望将索引的第一部分设置为常量表达式=0,以便它可以执行范围扫描。
An index_col_name specification can end with ASC or DESC. These keywords are permitted for future extensions for specifying ascending or descending index value storage. Currently, they are parsed but ignored; index values are always stored in ascending order. 
OPTIMIZE TABLE users;
KEY `foo` (`id`,`email_verified`)
+----+-------------+-------+-------+----------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys  | key     | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+----------------+---------+---------+------+------+--------------------------+
|  1 | SIMPLE      | users | index | email_verified | Index 4 | 6       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+----------------+---------+---------+------+------+--------------------------+
SELECT * FROM users WHERE verified = 0 ORDER BY id DESC LIMIT 20
(verified, id)
SELECT  *
FROM    users
WHERE   verified = 0
ORDER BY
        id DESC
LIMIT 20