为什么';MySQL是否在JOIN plus ORDER上使用主键?
这里有一个简单的例子(显然是MySQL): 上面的查询(同样,这正是我在生产中运行的查询)运行大约需要14秒。下面是在生产环境中执行的简化查询,如上面的用例所示: SELECT corder.id, invoice.invoice_no FROM corder LEFT JOIN invoice ON invoice.id=corder.invoice ORDER BY corder.id DESC LIMIT 400, 20; 此操作失败,并显示以下错误消息: ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' 错误1235(42000):此版本的MySQL尚不支持“LIMIT&IN/ALL/ANY/SOME子查询” 我使用的是MySQL 5.1.61,它在5.1系列中是相当新的(显然这在5.5.x中也不受支持)。您能试试这个版本吗(它基本上先获取为什么';MySQL是否在JOIN plus ORDER上使用主键?,mysql,indexing,sql-order-by,left-join,Mysql,Indexing,Sql Order By,Left Join,这里有一个简单的例子(显然是MySQL): 上面的查询(同样,这正是我在生产中运行的查询)运行大约需要14秒。下面是在生产环境中执行的简化查询,如上面的用例所示: SELECT corder.id, invoice.invoice_no FROM corder LEFT JOIN invoice ON invoice.id=corder.invoice ORDER BY corder.id DESC LIMIT 400, 20; 此操作失败,并显示以下错误消息:
corder
表的420行,保留其中的20行,然后进行3个外部联接):
您在加入中使用的
客户订单(发票)
上没有索引吗?我的意思是,在生产系统中。使用5行表进行测试没有什么价值。执行计划可能不同于实际计划(有很多行)。实际上,在我试图理解这一点时,我尝试添加了它,但没有任何区别(如果你仔细想想,这是意料之中的)。是的,我是在生产中这样做的——没有区别。第二,表是MyISAM还是InnoDB?这是有区别的。最后,你的最后一个(有问题的)查询是相当无用的。您(左)加入到customer\u invoice
,但在选择时不使用它。如果你发布一个有用的查询,那就更好了。否则,为什么要使用第四行,这只是第二行(但可能有很多重复行)?MyISAM。如果您愿意,您可以在该查询中添加铃铛和哨子,这不会有任何区别(我显然选择的不仅仅是订单ID)。0.09秒,而之前为12-14秒。这是我之前说过的好办法。敬你一杯,先生!我很难过,似乎没有办法强迫MySQL自己做这件事,但我想这是最好的了。
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+------+-------------+
| 1 | SIMPLE | co | ALL | NULL | NULL | NULL | NULL | 5 | |
| 1 | SIMPLE | ci | eq_ref | PRIMARY | PRIMARY | 3 | index_test_gutza.co.invoice | 1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+------+-------------+
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+------+----------------+
| 1 | SIMPLE | co | ALL | NULL | NULL | NULL | NULL | 5 | Using filesort |
| 1 | SIMPLE | ci | eq_ref | PRIMARY | PRIMARY | 3 | index_test_gutza.co.invoice | 1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+------+----------------+
SELECT
corder.id,
corder.public_id,
CONCAT(buyer.fname," ",buyer.lname) AS buyer_name,
corder.status,
corder.payment,
corder.reserved AS R,
corder.tracking_id!="" as A,
corder.payment_received as pay_date,
invoice.invoice_no AS inv,
invoice.receipt_no AS rec,
invoice.public AS pub_inv,
proforma.proforma_no AS prof,
proforma.public AS pub_pf,
corder.rating,
corder.rating_comments!="" AS got_comment
FROM
corder
LEFT JOIN user as buyer ON buyer.id=corder.buyer
LEFT JOIN invoice as invoice ON invoice.id=corder.invoice
LEFT JOIN invoice as proforma ON proforma.id=corder.proforma
ORDER BY
id DESC
LIMIT 400, 20;
SELECT
corder.id,
invoice.invoice_no
FROM
corder
LEFT JOIN invoice ON invoice.id=corder.invoice
ORDER BY
corder.id DESC
LIMIT 400, 20;
SELECT
corder.id,
corder.public_id,
CONCAT(buyer.fname," ",buyer.lname) AS buyer_name,
corder.status,
corder.payment,
corder.reserved AS R,
corder.tracking_id != "" AS A,
corder.payment_received AS pay_date,
invoice.invoice_no AS inv,
invoice.receipt_no AS rec,
invoice.public AS pub_inv,
proforma.proforma_no AS prof,
proforma.public AS pub_pf,
corder.rating,
corder.rating_comments!="" AS got_comment
FROM
corder
LEFT JOIN user as buyer ON buyer.id = corder.buyer
LEFT JOIN invoice AS invoice ON invoice.id = corder.invoice
LEFT JOIN invoice AS proforma ON proforma.id = corder.proforma
WHERE corder.id IN (
SELECT id
FROM corder
ORDER BY id DESC
LIMIT 400,20
)
ORDER BY
corder.id DESC;
ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
SELECT
corder.id,
corder.public_id,
CONCAT(buyer.fname," ",buyer.lname) AS buyer_name,
corder.status,
corder.payment,
corder.reserved AS R,
corder.tracking_id != "" AS A,
corder.payment_received AS pay_date,
invoice.invoice_no AS inv,
invoice.receipt_no AS rec,
invoice.public AS pub_inv,
proforma.proforma_no AS prof,
proforma.public AS pub_pf,
corder.rating,
corder.rating_comments!="" AS got_comment
FROM
( SELECT *
FROM corder
ORDER BY
id DESC
LIMIT 400, 20
)
AS corder
LEFT JOIN user as buyer ON buyer.id = corder.buyer
LEFT JOIN invoice AS invoice ON invoice.id = corder.invoice
LEFT JOIN invoice AS proforma ON proforma.id = corder.proforma
ORDER BY
corder.id DESC ;