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