Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 优化从销售表中购买的每个客户的选择产品详细信息_Mysql_Sql_Performance_Select - Fatal编程技术网

Mysql 优化从销售表中购买的每个客户的选择产品详细信息

Mysql 优化从销售表中购买的每个客户的选择产品详细信息,mysql,sql,performance,select,Mysql,Sql,Performance,Select,我有4张桌子、客户、产品、销售和销售项目。我使用下面的查询从中提取数据 SELECT ( SELECT c.name FROM Customers c WHERE s.customer_id=c.id ) customer ,( Select group_concat(description) FROM ( SELECT si.id

我有4张桌子、客户、产品、销售和销售项目。我使用下面的查询从中提取数据

SELECT (
            SELECT c.name 
            FROM Customers c
            WHERE s.customer_id=c.id
            ) customer
    ,(
        Select group_concat(description)
        FROM (
            SELECT si.id
                ,si.sale_id
                ,concat("x", si.Qty, " ", p.name, " ",(si.total)) description
            FROM Sale_Items si
            LEFT JOIN Products p ON p.id = si.product_id
            ) p
        where s.id = Sale_ID
        GROUP BY Sale_ID
        ) detail,
                            s.total
FROM Sales s
查询生成结果,但速度变慢,只有2000条记录(完成需要114秒)

我怎样才能使它更快

在这里进行了一次尝试


如果我们想继续使用相关子查询,我们可以取消内联视图
p

对于从
Sales
检索到的每一行,这都将具体化。外部查询中
WHERE
子句中的谓词不会被“推”到视图中。因此,物化视图(或MySQL术语中的“派生表”)将是一个完整的集合,我们将从中挑选出几行。我们将在
Sales
中的每一行重复这一点

解开这个派生表应该会给我们带来一些性能上的好处。对于从
Sales
返回的少量行,这是一种合理的方法,并定义了合适的索引。也就是说,如果我们使用
WHERE
子句限制外部查询检查的行数。对于大量的行,这些相关的子查询将降低性能

SELECT ( SELECT c.name 
           FROM Customers c
          WHERE c.id = s.customer_id
       ) AS customer

     , ( SELECT GROUP_CONCAT(CONCAT('x',si.Qty,' ',p.name,' ',si.total) ORDER BY p.name SEPARATOR '\r\n')
           FROM Sale_Items si
           LEFT
           JOIN Products p
             ON p.id = si.product_id
          WHERE si.sale_id = s.id
       ) AS detail

     , s.total

  FROM Sales s

 WHERE ... 

 ORDER
    BY ...
如果查询返回来自
Sales
的所有行,并且我们正在执行整个bloomin集,那么我倾向于避免相关子查询。(这是因为外部查询返回的每一行都会执行子查询。就性能而言,这些子查询将吃掉我们的午餐,因为返回了大量行。)

假设
id
customers
中是唯一的,我们通常使用连接操作会更好

SELECT c.name AS customer
     , d.detail
     , s.total
  FROM Sales s
  LEFT
  JOIN Customers c
    ON c.id = s.customer_id
  LEFT
  JOIN ( SELECT si.sale_id
              , GROUP_CONCAT(CONCAT('x',si.Qty,' ',p.name,' ',si.total) ORDER BY p.name SEPARATOR '\r\n') AS detail
           FROM Sale_Items si
           LEFT
           JOIN Products p
             ON p.id = si.product_id
          GROUP
             BY si.sale_id
       ) d
    ON d.sale_id = s.id
 ORDER
    BY ...

内联视图
d
对于大型集合来说会很昂贵;但至少我们只做了一次查询,将结果具体化为一个“派生表”。然后可以运行外部查询,并从派生表中检索行。

考虑处理应用程序代码中的数据显示问题。我怀疑生成的查询会更简单、更快。当我们为销售返回的每一行执行内联视图时,实现内联视图
p
的成本会很高。外部查询中的谓词不会被推送到视图定义中(这可能在较新版本的MySQL中有所改变)。
SELECT c.name AS customer
     , d.detail
     , s.total
  FROM Sales s
  LEFT
  JOIN Customers c
    ON c.id = s.customer_id
  LEFT
  JOIN ( SELECT si.sale_id
              , GROUP_CONCAT(CONCAT('x',si.Qty,' ',p.name,' ',si.total) ORDER BY p.name SEPARATOR '\r\n') AS detail
           FROM Sale_Items si
           LEFT
           JOIN Products p
             ON p.id = si.product_id
          GROUP
             BY si.sale_id
       ) d
    ON d.sale_id = s.id
 ORDER
    BY ...