繁体   English   中英

运行查询时,MySQL挂起。 如何提高效率?

[英]MySQL hangs when query is run. How can I make this more efficient?

我们正在尝试运行查询以获取所有未付款的发票。 当我运行查询时,它将挂起我们的整个系统。 我只是想知道是否有办法提高效率。 SQL不是我的强项。

$ query =“ SELECT SQL_CALC_FOUND_ROWS i.order_id,o。 ,acct。 ,(SELECT SUM(items.item_qty)AS数量,来自WHERE items.order_id = o.order_id的项目)AS order_qty
来自AS i项目
INNER JOIN订单AS o ON o.order_id = i.order_id
内联交易t ON.t_order_id = o.order_id
IN.JOIN帐户上的INNER JOIN帐户o.acct_id = acct.acct_id
INNER JOIN ship_to AS on ON.ship_id = st.ship_id
在哪里o.order_status = 7 AND o.order_date>'2009-05-01 00:00:00'
AND(SELECT SUM(items.item_price)从项目WHERE items.order_id = o.order_id)中获取的价格*(SELECT SUM(items.item_qty)从项目WHERE items.order_id = o.order_id中获取的AS数量+(o.order_ship_amount-(从t.order_id = o.order_id AND trans_pending = 0)的交易中选择总和(trans_amount)!= 0
AND acct.is_wholesale = 1
o.order_id的分组
o.order_date订购
LIMIT $ offset,$ limit“;

以下是所需表的表布局信息:

创建表items
item_id int(11)非空auto_increment,
order_id int(11)NOT NULL默认为'0',
prod_id int(11)NOT NULL默认为'0',
scat_id int(11)NOT NULL默认为'0',
inv_id int(11)NOT NULL默认为'0',
item_qty int(11)NOT NULL默认为'0',
item_price float(10,3)NOT NULL默认为'0.000',
item_mfg varchar(200)NOT NULL默认值'0',
item_group int(11)NOT NULL默认为'0',
item_ship_date datetime NOT NULL默认为'0000-00-00 00:00:00',
date_created datetime NOT NULL默认值'0000-00-00 00:00:00',
主键( item_id ),
密钥prod_idprod_id ),
KEY order_idorder_id ),
密钥inv_idinv_id ),
密钥scat_idscat_id
)ENGINE = MyISAM AUTO_INCREMENT = 834659 DEFAULT CHARSET = latin1

创建表orders
order_id int(11)NOT NULL auto_increment,
acct_id int(11)NOT NULL默认为'0',
order_date时间戳记NOT NULL默认CURRENT_TIMESTAMP,
order_confirm_date datetime NOT NULL默认为'0000-00-00 00:00:00',
order_approval_date datetime NOT NULL默认为'0000-00-00 00:00:00',
order_deposit_date datetime NOT NULL默认值'0000-00-00 00:00:00',
order_sent_to_mfg日期时间NOT NULL默认为'0000-00-00 00:00:00',
order_due_date datetime NOT NULL默认为'0000-00-00 00:00:00',
order_ship_date datetime NOT NULL默认为'0000-00-00 00:00:00',
order_exp_ship_date datetime NOT NULL默认为'0000-00-00 00:00:00',
order_ship_type文字NOT NULL,
order_ship_amount float(10,2)NOT NULL默认为'0.00',
order_mfg_name int(11)NOT NULL默认为'0',
order_notes文字NOT NULL,
order_status int(11)NOT NULL默认为'0',
ship_id int(11)NOT NULL默认为'0',
bill_id int(11)NOT NULL默认为'0',
order_requested_quote int(11)NOT NULL默认值'0',
order_submitted int(11)NOT NULL默认值'0',
order_origin int(11)NOT NULL默认为'0',
order_po_no varchar(25)NOT NULL默认值'',
qd_id int(11)NOT NULL默认为'0',
order_inactive int(11)NOT NULL默认为'0',
order_cancelled datetime NOT NULL order_cancelled 00:00:00',
site_id int(11)NOT NULL默认为'0',
主键( order_id ),
密钥ship_idship_id ),
密钥bill_idbill_id ),
密钥acct_idacct_id ),
KEY site_idsite_id
)ENGINE = MyISAM AUTO_INCREMENT = 20311622 DEFAULT CHARSET = latin1

创建表transactions
trans_id int(11)NOT NULL auto_increment,
order_id int(11)NOT NULL默认为'0',
trans_pnref文字NOT NULL,
trans_card_type文字NOT NULL,
trans_date datetime NOT NULL默认值'0000-00-00 00:00:00',
trans_amount float(10,2)NOT NULL默认为'0.00',
trans_type文字NOT NULL,
trans_tender文字NOT NULL,
trans_po_no文字NOT NULL,
trans_origin文字NOT NULL,
trans_rep int(11)NOT NULL默认为'0',
trans_po_received datetime NOT NULL默认值'0000-00-00 00:00:00',
trans_inactive int(11)NOT NULL默认值'0',
trans_pending int(11)NOT NULL默认为'0',
trans_secured int(11)NOT NULL默认为'0',
site_id int(11)NOT NULL默认为'0',
主键( trans_id ),
KEY cod_idorder_id ),
KEY site_idsite_id
)ENGINE = MyISAM AUTO_INCREMENT = 211554 DEFAULT CHARSET = latin1

创建表accounts
acct_id int(11)NOT NULL auto_increment,
acct_signup时间戳NOT NULL默认CURRENT_TIMESTAMP,
acct_first文字NOT NULL,
acct_last文字NOT NULL,
acct_company文字NOT NULL,
acct_email文字NOT NULL,
acct_email_cc文字NOT NULL,
acct_email_bcc文字NOT NULL,
acct_phone文字NOT NULL,
acct_fax文字NOT NULL,
acct_password文字NOT NULL,
acct_default_ship int(11)NOT NULL默认值'0',
acct_default_bill int(11)NOT NULL默认为'0',
is_account int(1)NOT NULL默认为'0',
is_wholesale int(1)NOT NULL默认值'0',
site_id int(11)NOT NULL默认为'0',
tpsg_id int(11)NOT NULL默认为'0',
主键( acct_id ),
密钥acct_default_shipacct_default_ship ),
密钥acct_default_billacct_default_bill ),
KEY site_idsite_id ),
按键tpsg_idtpsg_id
)ENGINE = MyISAM AUTO_INCREMENT = 264476 DEFAULT CHARSET = latin1

创建表ship_to
ship_id int(11)非空auto_increment,
acct_id int(11)NOT NULL默认为'0',
ship_first文字NOT NULL,
ship_last文字NOT NULL,
ship_company文字NOT NULL,
ship_address1文字NOT NULL,
ship_address2文字NOT NULL,
ship_city文字NOT NULL,
ship_state文字NOT NULL,
ship_zip文字NOT NULL,
ship_country文字NOT NULL,
ship_phone文字NOT NULL,
ship_fax文字NOT NULL,
ship_notes文字NOT NULL,
ship_inactive int(1)unsigned NOT NULL默认值'0',
主键( ship_id ),
密钥acct_idacct_id
)ENGINE = MyISAM AUTO_INCREMENT = 241339 DEFAULT CHARSET = latin1

我要此查询执行的操作是提取状态为7的所有订单的订单信息(在2009年5月1日之后),然后将订单中所有项目的价格乘以数量,然后将装运数量与从中减去已支付的金额并检查是否为0。此外,该帐户必须是批发帐户。

我知道此查询的效率很低,但是我不确定该怎么做。 我们的系统太不堪重负了,总体来说非常落后。

我将不胜感激任何帮助!

使用说明来分析查询执行计划: http : //dev.mysql.com/doc/refman/5.1/en/using-explain.htmlhttp://dev.mysql.com/doc/refman/5.1/en/说明.html

通常,WHERE中的子查询非常慢,请尝试将它们重写为JOIN。

它是WHERE子句中的子查询。 纳克蒂巴拉(Naktibala)在那儿撞到了头。

您也可以尝试为要从子查询中获取的数据创建一些临时表。 基本上,将您需要的数据放入临时表,然后将这些表通常加入基本查询中。 完成所有工作后,您可以简化/调整。

当您已经准备好通过order_id加入项目和交易时,我认为您可以删除子查询条件,并将支票移至HAVING。

尝试运行此查询:

SELECT SQL_CALC_FOUND_ROWS i.order_id, o.*, acct.*, SUM(items.item_qty) AS order_qty
FROM items AS i
INNER JOIN orders AS o ON o.order_id = i.order_id
INNER JOIN transactions AS t ON t.order_id = o.order_id
INNER JOIN accounts AS acct ON o.acct_id = acct.acct_id
INNER JOIN ship_to AS st ON o.ship_id = st.ship_id
WHERE o.order_status=7 AND o.order_date > '2009-05-01 00:00:00'
AND acct.is_wholesale=1
GROUP BY o.order_id
HAVING ( SUM(items.item_price) * SUM(items.item_qty) + o.order_ship_amount - SUM(transactions.trans_amount) ) != 0
ORDER BY o.order_date
LIMIT $offset, $limit

看看这是否更简单地描述了您的查询(并且效率不高)。

SELECT   
    o.order_id,  
    o.order_ship_amount,  
    SUM(i.item_qty * i.item_price) AS item_amount,  
    SUM(trans_amount) AS trans_amount,  
    ... etc.
FROM  
    orders AS o  
INNER JOIN accounts AS acct ON o.acct_id = acct.acct_id  
INNER JOIN ship_to AS st ON o.ship_id = st.ship_id  
INNER JOIN items AS i ON o.order_id = i.order_id  
LEFT JOIN transactions AS t ON t.order_id = o.order_id  
    AND trans_pending = 0  
WHERE   
    o.order_status = 7   
    AND o.order_date > '2009-05-01 00:00:00'  
    AND acct.is_wholesale = 1   
GROUP BY o.order_id  
HAVING item_amount + order_ship_amount - trans_amount != 0  
ORDER BY o.order_date  

确保您可以阅读和理解它-我还没有测试过。

SELECT   
    o.order_id,  
    o.order_ship_amount,  
    SUM(i.item_qty * i.item_price) AS item_amount,  
    (   SELECT SUM(trans_amount) FROM transactions
        WHERE order_id = o.order_id AND trans_pending = 0
    ) AS trans_amount,
    ... etc.
FROM  
    orders AS o  
INNER JOIN accounts AS acct ON o.acct_id = acct.acct_id  
INNER JOIN ship_to AS st ON o.ship_id = st.ship_id  
INNER JOIN items AS i ON o.order_id = i.order_id  
WHERE   
    o.order_status = 7   
    AND o.order_date > '2009-05-01 00:00:00'  
    AND acct.is_wholesale = 1   
GROUP BY o.order_id  
HAVING item_amount + order_ship_amount - trans_amount != 0  
ORDER BY o.order_date  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM