在大型mysql表中按类别和价格范围快速选择

时间:2015-05-21 13:26:53

标签: php mysql

我需要从具有特定类别ID和价格范围的大型MySQL表(~9000000行,4.5GiB)中选择一个随机产品。

我现在使用的解决方案大约需要30秒才能完成请求。

$query = mysqli_query($db, "SELECT MAX(id) FROM `products` WHERE category = $cat AND price >= $price_min AND price <= $price_max");
$f = mysqli_fetch_array($query);
$max_id = $f[0];
$random_id = rand(0, $max_id);
mysqli_free_result($query);

$query = mysqli_query($db, "SELECT * FROM `products` id=$random_id LIMIT 1");
$product = mysqli_fetch_assoc($query);

是否可以优化请求?

2 个答案:

答案 0 :(得分:1)

要获得一定的速度,您需要考虑确保category有索引。

但如果你使用它,你可以删除一个查询:

$query = mysqli_query(
    $db,
    "
        SELECT *
        FROM `products`
        WHERE
            `category` = $cat
            AND `price` BETWEEN $price_min AND $price_max
        ORDER BY RAND()
        LIMIT 1
    "
);

$product = mysqli_fetch_assoc($query);

希望这有帮助。

答案 1 :(得分:1)

使用EXPLAIN查看查询的执行计划。确保MySQL正在使用适当的索引来满足查询。

参考:https://dev.mysql.com/doc/refman/5.5/en/using-explain.html

此查询的相应索引将category作为前导列,后跟price,并包含id列。

举个例子:

CREATE INDEX products_IX1 ON products (category, price, id);

有了这个索引,我们期望EXPLAIN输出显示MySQL正在使用前两列对索引执行范围扫描操作(由key_len指示我们还希望EXPLAIN输出显示&#34;使用索引&#34;在Extra列中,因为索引是&#34;覆盖&#34;查询的索引。

注意

这与您提出的问题无关,但是......

代码示例易受攻击 SQL注入。结合到SQL语句文本中的潜在不安全值必须正确转义。

http://php.net/manual/en/mysqli.real-escape-string.php

更好的模式是使用预备语句绑定占位符