首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有LIMIT和UNION的Select查询性能问题

带有LIMIT和UNION的Select查询性能问题
EN

Stack Overflow用户
提问于 2019-08-09 02:47:52
回答 1查看 195关注 0票数 1

我想从我的mysql数据库中选择某些数据。我正在使用一个带LIMITUNION的php循环和sql语句。

问题:我的查询速度太慢了。一条UNION语句需要2-4秒。由于循环的原因,整个查询需要3分钟。有没有机会优化我的查询?

我尝试分离“三个”语句并合并结果。但这并不是真的更快。所以我认为UNION不是我的问题。

PHP/SQL

我的代码正在运行两个foreach循环。代码运行正常。但性能是问题所在。

代码语言:javascript
复制
$sql_country = "SELECT country FROM country_list"; 
foreach ($db->query($sql_country) as $row_country) { //first loop (150 entries)
    $sql_color = "SELECT color FROM color_list";

    foreach ($db->query($sql_color) as $row_color) { //second loop (10 entries)
        $sql_all = "(SELECT ID, price FROM company 
                            WHERE country = '".$row_country['country']."' 
                                AND color = '".$row_color['color']."'  
                                AND price BETWEEN 2.5 AND 4.5  
                                order by price DESC LIMIT 2)

                            UNION

                            (SELECT ID, price FROM company 
                            WHERE country = '".$row_country['country']."' 
                                AND color = '".$row_color['color']."'  
                                AND price BETWEEN 5.5 AND 8.2  
                                order by price DESC LIMIT 2)

                            UNION 

                            (SELECT ID, price FROM company 
                            WHERE country = '".$row_country['country']."' 
                                AND color = '".$row_color['color']."'  
                                AND price BETWEEN 8.5 AND 10.8  
                                order by price DESC LIMIT 2)";
        foreach ($db->query($sql_all) as $row_all) {
                $shopID[] = $row_all['ID']; //I just need these IDs
        }
    }
}

你有什么想法或提示可以更快地完成这项工作吗?

EN

回答 1

Stack Overflow用户

发布于 2019-08-11 00:35:45

(country, color, price, ID)上的索引应该可以将单个查询的性能从几秒钟提高到几毫秒,甚至更少。但是您仍然存在执行1500个查询的问题。根据您的系统,一次查询执行可能会增加大约10毫秒的开销,在您的情况下加起来是15秒。您需要找到一种方法来最小化查询的数量-在最好的情况下是单个查询。

对于较低的限制(如本例中的2 ),您可以组合多个具有不同偏移量的LIMIT 1子查询。我会动态生成这样的查询。

代码语言:javascript
复制
$priceRanges = [
    ['2.5', '4.5'],
    ['5.5', '8.2'],
    ['8.5', '10.8'],
];

$limit = 2;
$offsets = range(0, $limit - 1);

$queryParts = [];
foreach ($priceRanges as $range) {
    $rangeFrom = $range[0];
    $rangeTo   = $range[1];
    foreach ($offsets as $offset) {
        $queryParts[] = "
            select (
              select ID
              from company cmp
              where cmp.country = cnt.country
                and cmp.color   = clr.color
                and cmp.price between {$rangeFrom} AND {$rangeTo}
              order by cmp.price desc
              limit 1
              offset {$offset}
            ) as ID
            from country_list cnt
            cross join color_list clr
            having ID is not null
        ";
    }
}

$query = implode(' UNION ALL ', $queryParts);

这将生成一个相当长的UNION查询。您可以看到PHP demo on rexester.comSQL demo on db-fiddle.com

我不能保证它会更快。但这值得一试。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57418970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档