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

性能和排序,以及mysql和php之间的独特性,php,mysql,Php,Mysql,在这种情况下,哪种方法或混合方法执行得最快 $year = db_get_fields("select distinct year from car_cache order by year desc"); 或 我听说mysql上的distinct对大型查询的性能有很大影响,这个表可以有一百万行或更多行。我想知道什么样的数据库类型组合,Innodb或MyISAM,也能起到最好的作用。我知道很多优化都非常依赖于查询。Year是一个无符号的数字,但其他字段是不同长度的varchar,我知道这可能也会

在这种情况下,哪种方法或混合方法执行得最快

$year = db_get_fields("select distinct year from car_cache order by year desc");

我听说mysql上的distinct对大型查询的性能有很大影响,这个表可以有一百万行或更多行。我想知道什么样的数据库类型组合,Innodb或MyISAM,也能起到最好的作用。我知道很多优化都非常依赖于查询。Year是一个无符号的数字,但其他字段是不同长度的varchar,我知道这可能也会有所不同。例如:

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

我了解到,使用新的innodb多键方法可以使这样的查询非常快速。但是distinct和ORDERBY子句对我来说是危险信号。

让MySQL尽可能多地工作。如果它的工作效率不高,则可能设置不正确(无论是为您试图运行的查询建立适当的索引,还是使用排序缓冲区设置)

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

下面是我拥有的一个dev数据库的一些示例输出。还要注意,该数据库位于执行查询的网络上的另一台服务器上

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 |
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
如果我尝试相同的查询,除了将
SerialNumber
列替换为一个未索引的列,那么它将永远无法运行,因为MySQL必须检查所有9700万行

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

关于你的最后一个问题:

select distinct line from car_cache
where year='$postyear' and make='$postmake'
order by line desc
这也应该没有问题,只要确保您在
make
上有一个复合索引,并且可能在
上有一个索引

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


希望有帮助。

对于最终查询,最好的索引是
(年份、品牌、行)
(品牌、年份、行)
select distinct line from car_cache
where year='$postyear' and make='$postmake'
order by line desc