性能和排序,以及mysql和php之间的独特之处

Wol*_*lfe 6 php mysql

在这样的情况下,哪种方法或方法组合执行最快?

$year = db_get_fields("select distinct year from car_cache order by year desc");
Run Code Online (Sandbox Code Playgroud)

要么

$year = db_get_fields("select year from car_cache");
$year = array_unique($year);
sort($year);
Run Code Online (Sandbox Code Playgroud)

我听说mysql上的独特内容对于大型查询来说是一个真正的大性能,而且这个表可能有一百万行甚至更多.我想知道什么样的数据库类型组合,Innodb或MyISAM,也会起作用.我知道许多优化都依赖于查询.Year是一个无符号数,但其他字段是不同长度的varchar,我知道这也可能有所不同.如:

$line = db_get_fields("select distinct line from car_cache where year='$postyear' and make='$postmake' order by line desc");
Run Code Online (Sandbox Code Playgroud)

我读到使用新的innodb多键方法可以非常快速地进行这样的查询.但是,明确的和order by子句对我来说是个危险信号.

dre*_*010 3

让 MySQL 做尽可能多的工作。如果它的工作效率不高,那么事情可能没有正确设置(无论是您尝试运行的查询的正确索引,还是排序缓冲区的设置)。

如果列上有索引year,那么使用DISTINCT应该是有效的。如果不这样做,则需要进行全表扫描才能获取不同的行。如果您尝试在 PHP 而不是 MySQL 中对不同的行进行排序,那么您(可能)会从 MySQL 向 PHP 传输更多的数据,并且 PHP 在消除重复项之前会消耗更多的内存来存储所有这些数据。

这是我拥有的开发数据库的一些示例输出。另请注意,该数据库位于网络上与执行查询的不同服务器上。

SELECT COUNT(SerialNumber) FROM `readings`;
> 97698592

SELECT SQL_NO_CACHE DISTINCT `SerialNumber`
FROM `readings`
ORDER BY `SerialNumber` DESC
LIMIT 10000;
> Fetched 10000 records.  Duration: 0.801 sec, fetched in: 0.082 sec

> EXPLAIN *above_query*
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
| id | select_type | table    | type  | possible_keys | key     | key_len | ref  | rows | Extra                                                     |
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
|  1 | SIMPLE      | readings | range | NULL          | PRIMARY | 18      | NULL |   19 | Using index for group-by; Using temporary; Using filesort |
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

如果我尝试相同的查询,除了用SerialNumber非索引列替换该列之外,那么它需要永远运行,因为 MySQL 必须检查所有 9700 万行。

部分效率与您期望返回的数据量有关。如果我稍微修改上面的查询以对列time(读取的时间戳)进行操作,那么需要 1 分 40 秒才能获得 273,505 次的不同列表,其中大部分开销是通过网络传输所有记录。因此,请记住要返回的数据量的限制,您希望将尝试获取的数据量保持在尽可能低的水平。

至于您的最终查询:

select distinct line from car_cache
where year='$postyear' and make='$postmake'
order by line desc
Run Code Online (Sandbox Code Playgroud)

这应该也没有问题,只需确保您在year和上有一个复合索引make,并且可能在 上有一个索引line

最后一点,我用于读数表的引擎是 InnoDB,我的服务器是:5.5.23-55-log Percona Server (GPL), Release 25.3这是 Percona Inc. 的 MySQL 版本。

希望有帮助。