[英]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_id
( prod_id
),
KEY order_id
( order_id
), KEY order_id
( order_id
),
KEY inv_id
( inv_id
), 密钥inv_id
( inv_id
),
KEY scat_id
( scat_id
) 密钥scat_id
( scat_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_id
( ship_id
),
KEY bill_id
( bill_id
), 密钥bill_id
( bill_id
),
KEY acct_id
( acct_id
), 密钥acct_id
( acct_id
),
KEY site_id
( site_id
) KEY site_id
( site_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_id
( order_id
),
KEY site_id
( site_id
) KEY site_id
( site_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_ship
( acct_default_ship
),
KEY acct_default_bill
( acct_default_bill
), 密钥acct_default_bill
( acct_default_bill
),
KEY site_id
( site_id
), KEY site_id
( site_id
),
KEY tpsg_id
( tpsg_id
) 按键tpsg_id
( tpsg_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_id
( acct_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.html和http://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.