Mysql
改進慢查詢。附慢查詢日誌
下面是我的 .NET 應用程序執行時的慢查詢日誌。請讓我知道如何提高查詢的性能:
TCP Port: 3306, Named Pipe: (null) Time Id Command Argument # Time: 110805 13:25:39 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.015625 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1373 use stockist; SET timestamp=1312530939; SELECT SUM(GROSSAMOUNT) FROM BILLDETAILS WHERE MONTH(BILLDATE) = 8 AND YEAR(BILLDATE) = 2011; # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.000000 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1373 SET timestamp=1312530939; SELECT COUNT(BILLNO) FROM BILLDETAILS WHERE MONTH(BILLDATE) = 8 AND YEAR(BILLDATE) = 2011; # Time: 110805 13:30:32 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.078125 Lock_time: 0.046875 Rows_sent: 1 Rows_examined: 1374 SET timestamp=1312531232; SELECT A.BILLNO AS BILL_NO, DATE_FORMAT(A.BILLDATE,'%d/%m/%Y') AS BILL_DATE, B.PARTYNAME AS PARTY_NAME, A.NETAMOUNT AS NET_AMOUNT FROM BILLDETAILS A, PARTYMASTER B WHERE A.PARTYID = B.PARTYID AND MONTH(A.BILLDATE) = 8 AND YEAR(A.BILLDATE) = 2011 ORDER BY A.BILLNO, A.BILLDATE; # Time: 110805 13:30:44 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.296875 Lock_time: 0.031250 Rows_sent: 407 Rows_examined: 19552 SET timestamp=1312531244; select a.itemcode as Item_Code, a.itemname as Item_Name, a.stockinhand as Stock_In_Hand, b.mrp As MRP, round((a.stockinhand * b.mrp),2) As Value, date_format(b.invoicedate,'%d/%m/%Y') As Stock_Date from itemmaster a, stockentry b where a.itemid = b.itemid and invoicedate = (select max(invoicedate) from stockentry where itemid = b.itemid) group by a.itemname order by a.itemname; # Time: 110805 13:30:55 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.000000 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1 SET timestamp=1312531255; SELECT * FROM REMARKSETTINGS; # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.000000 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1 SET timestamp=1312531255; SELECT * FROM BILLINGSETTINGS; # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.015625 Lock_time: 0.015625 Rows_sent: 1 Rows_examined: 1373 SET timestamp=1312531255; SELECT MAX(BILLNO) FROM BILLDETAILS WHERE YEAR(BILLDATE) = 2011; # Time: 110805 13:30:58 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.031250 Lock_time: 0.000000 Rows_sent: 184 Rows_examined: 3266 SET timestamp=1312531258; SELECT B.RECORDID, A.ITEMCODE, A.ITEMNAME, A.STOCKINHAND, B.SALEPRICE FROM ITEMMASTER A, STOCKENTRY B WHERE A.ITEMID = B.ITEMID AND RECORDID = (SELECT MAX(RECORDID) FROM STOCKENTRY WHERE ITEMID = A.ITEMID) AND A.STOCKINHAND > 0 AND B.SALEPRICE > 0 AND B.INVOICEDATE IS NOT NULL ORDER BY A.ITEMNAME, B.INVOICEDATE; # Time: 110805 13:31:21 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.031250 Lock_time: 0.000000 Rows_sent: 184 Rows_examined: 2898 SET timestamp=1312531281; SELECT B.RECORDID, A.ITEMCODE, A.ITEMNAME, A.STOCKINHAND, B.SALEPRICE FROM ITEMMASTER A, STOCKENTRY B WHERE A.ITEMID = B.ITEMID AND RECORDID = (SELECT MAX(RECORDID) FROM STOCKENTRY WHERE ITEMID = A.ITEMID) AND A.STOCKINHAND > 0 AND B.SALEPRICE > 0 AND B.INVOICEDATE IS NOT NULL AND A.ITEMNAME LIKE '%'; # Time: 110805 13:36:31 # User@Host: root[root] @ localhost [127.0.0.1] # Query_time: 0.250000 Lock_time: 0.000000 Rows_sent: 407 Rows_examined: 20367 SET timestamp=1312531591; select c.categoryname, a.itemcode as Item_Code, a.itemname as Item_Name, a.stockinhand as Stock_In_Hand, b.mrp As MRP, round((a.stockinhand * b.mrp),2) As Value, date_format(b.invoicedate,'%d/%m/%Y') As Stock_Date, D.TradeName, D.OwnerAddress, D.OwnerTinNo from itemmaster a, stockentry b, categorymaster c, OwnerDetails D where a.itemid = b.itemid and a.categoryid = c.categoryid and invoicedate = (select max(invoicedate) from stockentry where itemid = b.itemid) group by a.categoryid, a.itemname order by a.itemname;
一個突出的領域是您訪問 BillDetails 表的方式。所有查詢似乎都在 BillDate 上使用 MONTH 和 YEAR 運算符。例如:
SELECT SUM(GROSSAMOUNT) FROM BILLDETAILS WHERE MONTH(BILLDATE) = 8 AND YEAR(BILLDATE) = 2011;
這種方法需要訪問 BillDetails 中的每條記錄。更好的方法是索引 BillDate 並按如下方式查詢:
SELECT SUM(GROSSAMOUNT) FROM BILLDETAILS WHERE BILLDATE BETWEEN '2011-08-01' AND '2011-08-31';
看起來您目前沒有太多數據(1373 行),因此上述差異目前將是最小的,當數量增加時更顯著。