如何优化我的MySQL查询?

时间:2012-10-07 13:25:59

标签: mysql optimization query-optimization

我有两张桌子 发票(   Id,   Status,   VendorId,   CustomerId,   OrderDate,   InvoiceFor, )

InvoiceItem(   Id,   Status,   InvoiceId,   ProductId,   PackageQty,   PackagePrice, )

这里invoice.id = invoiceItem.invoiceId(Foregin key) 和Id字段是主键(big int) 这些表包含100000(发票)和450000(invoiceItem)行


现在我必须编写一个查询,该查询将返回发票的分类帐,其中发票为= 55或66且在某个日期范围内。 我还必须返回最后一个采用日期,该日期将包含该特定客户之前的产品生产日期。


输出应该是 OrderDate,InvoiceId,CustomerId,ProductId,LastTaken,PackageQty,PackagePrice


所以我写下面的查询

SELECT a.*, (
    SELECT MAX(ivv.orderdate)
    FROM invoice AS ivv , invoiceItem AS iiv 
    WHERE ivv.id=iiv.invoiceid
    AND iiv.ProductId=a.ProductId AND ivv.CustomerId=a.CustomerId AND ivv.orderDate<a.orderdate
) AS lastTaken FROM (
    SELECT iv.Id, iv.OrderDate, iv.CustomerId, iv.InvoiceFor, ii.ProductId,     
    ii.PackageQty, ii.PackagePrice
    FROM invoice AS iv, invoiceitem AS ii
    WHERE iv.id=ii.InvoiceId 
    AND iv.InvoiceFor IN (55,66)
    AND iv.Status=0 AND ii.Status=0 
    AND OrderDate BETWEEN '2011-01-01' AND '2011-12-31'
    ORDER BY iv.orderdate, iv.Id ASC 
) AS a

但我总是把时间浪费掉。我将如何解决问题?

此查询的说明如下: enter image description here

2 个答案:

答案 0 :(得分:0)

在OrderDate和InvoiceFor属性上创建索引。它应该快得多。

答案 1 :(得分:0)

关于查询本身的两点:

  1. 学习使用正确的JOIN语法。在WHERE条款中进行连接就像在莎士比亚英语中写问题一样。
  2. 子查询中的ORDER BY应位于最高级别之外。
  3. 然而,这些都不是杀戮性能。问题是SELECT子句中的子查询。我认为问题是你的SELECT子句中的子查询没有直接加入这两个表。请尝试将iiv.InvoiceId = ivv.InvoiceId包括在内,最好包含ON条款。

    如果这不起作用,请尝试索引策略。以下索引应该可以提高该子查询的性能:

    • InvoiceItem(ProductId)的索引
    • 发票上的索引(CustomerId,OrderDate)

    这应该允许MySQL从索引运行子查询,而不是全表扫描,这应该是一个很大的性能改进。