我有超过6000个结果,使用分页大约超过235页。当我点击第一页时,它加载的速度非常快,大约300ms,直到第40页。在那之后,页面加载时间就会下降,大约需要30 ~ 40+秒。我使用的是索引数据库。我试着用mysql捕获查询,但不喜欢它。谁能帮帮我。
php:
$sql = mysql_query("SELECT * FROM data WHERE (car = '$cars') AND (color = '$color' AND price BETWEEN '".$min."' AND '".$max."'
ORDER BY price LIMIT {$startpoint} , {$limit}");索引:
data 0 PRIMARY 1 id A 106199 NULL NULL BTREE
data 1 car_index 1 car A 1799 NULL NULL BTREE
data 1 car_index 2 color A 2870 NULL NULL BTREE
data 1 car_index 3 price A 6247 NULL NULL BTREE
data 1 car_index 4 location A 106199 NULL NULL BTREE 发布于 2015-08-23 09:54:49
这是MySQL (和其他数据库系统)的常见问题。使用LIMIT + OFFSET (这是您隐含地与LIMIT x,y一起使用的)一开始效果很好,但随着读取的行数增加,速度会呈指数级下降。添加索引绝对是很好的第一步,因为您应该始终基于索引查询数据,以避免全表扫描。
仅仅有一个关于价格的索引是不够的,因为你还有其他的WHERE属性。基本上,这就是MySQL正在做的事情:假设$limit = 25和$startPoint = 0,MySQL将从头开始读取表,并在找到25个匹配的行后停止并返回它们。假设它在第一次迭代中读取了500行。因为它不知道如何直接跳转到第25个匹配行(表中的第500行),所以它将再次从头开始读取,跳过前25个匹配行并返回下一个匹配行。让我们假设这个迭代还需要读取500个额外的行。
现在您知道问题出在哪里了。对于每次迭代,MySQL将不得不从头开始读取所有行,这将以指数级增加返回row所需的时间。
在我的示例中,要获取100 (25 *4次迭代)行,MySQL必须读取500 + 1000 + 1500 + 2000 = 5000行,而您可以预期它只读取500 *4=2000行。要获取1000 (25 * 40次迭代)行,MySQL必须读取500 + 1000 + 1500 + ... 20000 = 410,000行!!这远远超过了您预期的500 * 40 = 20,000行。
为了优化您的查询,首先只选择您需要的数据(没有SELECT *)。那么诀窍就是记住最后获取的id。
$lastFetchedId = 0;
do {
$sql = mysql_query("SELECT * FROM data WHERE id > $lastFetchedId AND (car = '$cars' AND color = '$color' AND price BETWEEN '".$min."' AND '".$max."')
ORDER BY price LIMIT {$limit}");
$hasFoundRows = false;
while ($row = mysql_fetch_assoc($sql)) {
$hasFoundRows = true;
$lastFetchedId = $row['id'];
// do something with the row
}
} while ($hasFoundRows === false);只有在WHERE子句中使用的所有列上都有索引时,MySQL才能很好地处理排序。这样想一想:如果数据没有排序,MySQL如何知道哪些行将匹配以及匹配的行在哪里。为了能够对结果进行排序并只返回一个子集,MySQL需要构建一个包含所有实际匹配的行的排序列表。这意味着遍历整个表,首先获取所有匹配的行,然后对它们进行排序,最后只返回其中的一小部分。
希望这能帮助你更好地理解在这里你可以做得更好:)
发布于 2015-08-23 08:55:54
最好在这里发布表结构,看看您有哪些索引。请在列价格上添加索引,这样可以提高查询性能。
干杯
https://stackoverflow.com/questions/32162136
复制相似问题