简体   繁体   English

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

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

We are trying to run a query to get all unpaid invoices. 我们正在尝试运行查询以获取所有未付款的发票。 When I run the query it hangs our whole system. 当我运行查询时,它将挂起我们的整个系统。 I am just wondering if there is a way I can make this more efficent. 我只是想知道是否有办法提高效率。 SQL isn't my strong point. SQL不是我的强项。

$query = "SELECT SQL_CALC_FOUND_ROWS i.order_id, o. , acct. , (SELECT SUM(items.item_qty) AS qty FROM items WHERE items.order_id = o.order_id ) AS order_qty $ 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
FROM items AS i 来自AS i项目
INNER JOIN orders AS o ON o.order_id = i.order_id INNER JOIN订单AS o ON o.order_id = i.order_id
INNER JOIN transactions AS t ON t.order_id = o.order_id 内联交易t ON.t_order_id = o.order_id
INNER JOIN accounts AS acct ON o.acct_id = acct.acct_id IN.JOIN帐户上的INNER JOIN帐户o.acct_id = acct.acct_id
INNER JOIN ship_to AS st ON o.ship_id = st.ship_id INNER JOIN ship_to AS on ON.ship_id = st.ship_id
WHERE o.order_status=7 AND o.order_date > '2009-05-01 00:00:00' 在哪里o.order_status = 7 AND o.order_date>'2009-05-01 00:00:00'
AND (SELECT SUM(items.item_price) AS price FROM items WHERE items.order_id = o.order_id) * (SELECT SUM(items.item_qty) AS qty FROM items WHERE items.order_id = o.order_id) + o.order_ship_amount-(SELECT sum(trans_amount) FROM transactions WHERE t.order_id = o.order_id AND trans_pending = 0)!=0 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 AND acct.is_wholesale = 1
GROUP BY o.order_id o.order_id的分组
ORDER BY o.order_date o.order_date订购
LIMIT $offset, $limit"; LIMIT $ offset,$ limit“;

Here is the table layout information for the needed tables: 以下是所需表的表布局信息:

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

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

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

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

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

What I want this query to do is to pull the order information for all orders that have a status of 7 are after May 1, 2009 and add up the prices for all items in the order multiplied by the quantity then add the shipment amount and and subtract from it the amount paid and check if it's not 0.Also, the account has to be a wholesale account. 我要此查询执行的操作是提取状态为7的所有订单的订单信息(在2009年5月1日之后),然后将订单中所有项目的价格乘以数量,然后将装运数量与从中减去已支付的金额并检查是否为0。此外,该帐户必须是批发帐户。

I know this query is very inefficient but I am not sure how else to do it. 我知道此查询的效率很低,但是我不确定该怎么做。 Our system is so overwhelmed it is very laggy in general. 我们的系统太不堪重负了,总体来说非常落后。

I would appreciate any help! 我将不胜感激任何帮助!

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

In general subqueries in WHERE are very slow, try to rewrite them as JOIN. 通常,WHERE中的子查询非常慢,请尝试将它们重写为JOIN。

It is the subqueries in the WHERE clause. 它是WHERE子句中的子查询。 Naktibala hit the nail on the head there... 纳克蒂巴拉(Naktibala)在那儿撞到了头。

You can also try to create some temporary tables for the data you are getting for your subqueries. 您也可以尝试为要从子查询中获取的数据创建一些临时表。 Basically, put the data you will need to temp table(s), then JOIN those table(s) normally to your base query. 基本上,将您需要的数据放入临时表,然后将这些表通常加入基本查询中。 Once that all works you can streamline/tweak. 完成所有工作后,您可以简化/调整。

As you allready join items and transactions by order_id, I think that you can drop your subquery condition, and move checks to HAVING. 当您已经准备好通过order_id加入项目和交易时,我认为您可以删除子查询条件,并将支票移至HAVING。

Try running this query: 尝试运行此查询:

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

See if this describes your query a little more simply (and isn't a bit more efficient.) 看看这是否更简单地描述了您的查询(并且效率不高)。

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  

Make sure you can read and understand it - I haven't tested it. 确保您可以阅读和理解它-我还没有测试过。

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