簡體   English   中英

通過慢速查詢日志改善MySQL查詢性能

[英]improve MySQL query performance from slow query log

我在MySQL配置中打開了慢查詢監視器。

下面是查詢和時間:

時間:160330 20:54:11用戶@主機:用戶[用戶] @ [xx.xx.xxx.xxx]查詢時間:8.794170鎖定時間:0.000141發送的行數:3942已檢查的行數:47442825 SET timestamp = 1459371251;

SELECT (SELECT (CASE WHEN ce_type = 'IN' then SUM(payment_amount)
                                END) as debit
                        FROM customer_payment_options cpo
                        WHERE wallet_id=cw.id
                        AND (cpo.real_account_type='HQ')
                        AND cpo.source_country_id='40'
                        GROUP BY cpo.wallet_id)
                    as debit,
                    (SELECT SUM(payment_amount)
                                 as credit
                        FROM customer_payment_options cpo
                        WHERE wallet_id=cw.id
                        AND (cpo.real_account_type='HQ')
                        AND cpo.tran_id IS NOT NULL
                        AND cpo.source_country_id='40'
                        GROUP BY cpo.wallet_id)
                    as credit

                    FROM customer_wallet cw
                    WHERE cw.company_id='1'
                    AND cw.currency='40'
                    AND cw.is_approved = '1'
                    AND DATE(cw.date_added) < '2016-03-30';

customer_payment_options索引:

company_id
tran_id
ce_id
wallet_id

我應該怎么做才能改善其性能?

說明

http://i.stack.imgur.com/iH8rt.png

施瑪

CREATE TABLE `customer_payment_options` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`local_branch_id` int(11) NOT NULL,
`tran_id` bigint(11) DEFAULT NULL,
`ce_id` int(11) DEFAULT NULL,
`wallet_id` int(11) DEFAULT NULL,
`reward_credit_id` int(11) DEFAULT NULL,
`ce_invoice_id` varchar(32) DEFAULT NULL,
`ce_type` enum('IN','OUT') DEFAULT NULL,
`payment_type` enum('CASH','DEBIT','CREDIT','CHEQUE','DRAFT','BANK_DEPOSIT','EWIRE','WALLET','LOAN','REWARD_CREDIT') NOT NULL,
`payment_amount` varchar(20) NOT NULL,
`payment_type_number` varchar(100) DEFAULT NULL,
`source_country_id` int(11) NOT NULL,
`real_account_id` int(11) DEFAULT NULL,
`real_account_type` enum('LOCAL','HQ') DEFAULT NULL,
`date_added` datetime NOT NULL,
`event_type` enum('MONEY_TRANSFER','CURRENCY_EXCHANGE','WALLET') DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`),
KEY `real_account_type` (`real_account_type`),
KEY `tran_id` (`tran_id`),
KEY `ce_id` (`ce_id`),
KEY `wallet_id` (`wallet_id`),
CONSTRAINT `customer_payment_options_ibfk_4` FOREIGN KEY (`wallet_id`) REFERENCES `customer_wallet` (`id`),
CONSTRAINT `customer_payment_options_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`),
CONSTRAINT `customer_payment_options_ibfk_2` FOREIGN KEY (`tran_id`) REFERENCES `transaction` (`id`),
CONSTRAINT `customer_payment_options_ibfk_3` FOREIGN KEY (`ce_id`) REFERENCES `currency_exchange` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=412 DEFAULT CHARSET=utf8

CREATE TABLE `customer_wallet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`wallet_unique_id` varchar(100) DEFAULT NULL,
`company_id` int(11) NOT NULL,
`branch_admin_id` int(11) DEFAULT NULL,
`emp_id` int(11) DEFAULT NULL,
`emp_type` enum('SUPER_ADMIN','ADMIN','AGENT_ADMIN','AGENT','OVER_AGENT_ADMIN','OVER_AGENT') DEFAULT NULL,
`cus_id` bigint(11) NOT NULL,
`tran_id` bigint(11) DEFAULT NULL,
`beehive_id` int(11) DEFAULT NULL,
`type` enum('DEPOSIT','WITHDRAW','TRANSACTION') NOT NULL,
`sub_type` enum('MONEY_TRANSFER','BEEHIVE_DEPOSIT') DEFAULT NULL,
`credit_in` varchar(20) DEFAULT NULL,
`credit_out` varchar(20) DEFAULT NULL,
`currency` varchar(20) NOT NULL,
`date_added` datetime NOT NULL,
`note` varchar(255) DEFAULT NULL,
`location` enum('DIRECT') DEFAULT NULL,
`is_approved` enum('0','1') NOT NULL DEFAULT '1',
`idebit_issconf` varchar(50) DEFAULT NULL,
`idebit_issname` varchar(50) DEFAULT NULL,
`idebit_isstrack2` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `cus_id` (`cus_id`),
KEY `company_id` (`company_id`),
KEY `branch_admin_id` (`branch_admin_id`),
KEY `emp_id` (`emp_id`),
KEY `tran_id` (`tran_id`),
KEY `beehive_id` (`beehive_id`),
CONSTRAINT `customer_wallet_ibfk_1` FOREIGN KEY (`cus_id`) REFERENCES `customers` (`id`),
CONSTRAINT `customer_wallet_ibfk_2` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`),
CONSTRAINT `customer_wallet_ibfk_3` FOREIGN KEY (`tran_id`) REFERENCES `transaction` (`id`),
CONSTRAINT `customer_wallet_ibfk_4` FOREIGN KEY (`emp_id`) REFERENCES `employees` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8

您正在對每個錢包ID進行相關查詢,以獲取相應的借方和貸方。 看來您每個錢包ID都獲得了一條記錄。 這很忙。 根據您的常用條件加入到客戶付款表(包括每個錢包ID的加入)。 然后,將CASE簡化為SUM(case / when),分別作為借項/貸項。

我不知道您在表列中使用的基本條件,但我什至會套期保值(並且確實)不包括CE_TYPE ='IN',因為這似乎是借項的基礎,並且您不希望將其錯誤地計入貸方太。 同樣,不知道字段,trans_id,類型的相關性。

現在,如上所述,在各個字段上具有單個索引將無助於優化此查詢。 我建議以下指標。

表索引customer_wallet(company_id,is_approved,貨幣,id,date_added)customer_payment_options(wallet_id,account_type,country_id)

SELECT
      cw.wallet_id,
      SUM( case when cpo.ce_type = 'IN'
                then cpo.payment_amount
                ELSE 0 end ) as Debit,
      SUM( case when NOT cpo.ce_type = 'IN' 
                     AND cpo.tran_id IS NOT NULL
                then cpo.payment_amount
                ELSE 0 end ) as Credit
   FROM 
      customer_wallet cw
         JOIN customer_payment_options cpo
            ON cw.id = cpo.wallet_id
           AND cpo.real_account_type = 'HQ'
           AND cpo.source_country_id = '40'
   WHERE 
          cw.company_id = '1'
      AND cw.currency = '40'
      AND cw.is_approved = '1'
      AND cw.date_added < '2016-03-30'
   GROUP BY
      cw.id

另一條評論。 如果您的ID列,貨幣標志,國家/地區ID,已批准實際上是表結構中的數字值,請刪除引號,然后直接對數字值進行比較。 另外,為您的date_add。 您有基於DATE(date_added)的那個。 在列上執行功能不能充分利用索引。 由於date()剝奪了日期/時間戳列的任何時間部分,並且您要求添加的所有日期均少於3月30日,因此3月29日@ 11:59:59 pm的添加日期仍少於3月30日的12:上午00:00,因此不需要日期轉換。

正如伊萬(Ivan)所言(如下所示),如果您希望獲得所有電子錢包ID(無論是否付款)(借記或貸記),請從聯接更改為左聯接。

您需要添加索引和多列索引以使其快速。 請記住,如果表很大,那么額外的索引會降低插入速度,因為索引文件更新將花費更多時間。

如果col1和col2上存在多列索引,則可以直接獲取適當的行。 如果col1和col2上存在單獨的單列索引,那么優化器將嘗試使用索引合並優化(請參見第8.2.1.4節“索引合並優化”),或者通過確定哪個索引排除更多行來嘗試查找限制性最大的索引。並使用該索引來獲取行。

如果表具有多列索引,則優化器可以使用索引的任何最左前綴來查找行。 例如,如果在(col1,col2,col3)上有一個三列索引,則在(col1),(col1,col2)和(col1,col2,col3)上都有索引搜索功能。

閱讀更多

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM