2012-02-15 181 views
0

我有這樣的查詢(由Hibernate生成 - 編輯爲了更清楚 - 下面你會發現完整的查詢):提高查詢性能

select 
visitgroup0_.VISIT_ID as col_0_0_ ... 
from 
ADM_VISIT_GROUP visitgroup0_, 
ADM_CONTACT_OWNER contactown1_ 
where 
visitgroup0_.TIME>'2012-02-14 02:59:24' and 
visitgroup0_.VENDOR_ID='***' and 
visitgroup0_.CONTACT_STATE='PROSPECT' and 
contactown1_.CONTACT_ID=visitgroup0_.CONTACT_ID and 
contactown1_.OWNER_ID='***' order by visitgroup0_.TIME desc limit 30; 

簡單地說,我登錄本公司網站的客戶訪問,每一個客戶都分配所有者 - 銷售代表。我需要向所有者訪問他的聯繫人。

訪問存儲在ADM_VISIT_GROUP表中 - > 200 000行,訪問具有指向ADM_CONTACT的contact_id列。 聯繫人存儲在ADM_CONTACT表中 - 大約500 000行。 聯繫人的所有權存儲在ADM_CONTACT_OWNER表中 - 與ADM_CONTACT中的行數差不多相同。

說明顯示:

CREATE TABLE `ADM_VISIT_GROUP` (
    `ID` char(128) COLLATE utf8_polish_ci NOT NULL, 
    `UUID` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `CONTACT_STATE` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `VISIT_ID` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `HOST` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `IP` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `LOCATION` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `URI` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `TIME` datetime DEFAULT NULL, 
    `CONVERSATION` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `DURATION` bigint(20) DEFAULT NULL, 
    `VISIT_SOURCE` varchar(255) COLLATE utf8_polish_ci NOT NULL, 
    `VISIT_SOURCE_HOST` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `VISIT_SOURCE_KEYWORDS` varchar(1024) COLLATE utf8_polish_ci DEFAULT NULL, 
    `VISIT_SOURCE_DETAILS` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `VISIT_SCORE` bigint(20) DEFAULT NULL, 
    `CLIENT` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `EMAIL` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `CONTACT_ID` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `CONVERSATION_ID` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `IP_ORGANIZATION` varchar(255) COLLATE utf8_polish_ci DEFAULT NULL, 
    `ISP_ONLY` tinyint(1) DEFAULT NULL, 
    `VENDOR_ID` varchar(255) COLLATE utf8_polish_ci NOT NULL, 
    PRIMARY KEY (`ID`), 
    KEY `FK_VISIT_GROUP_VENDOR_ID` (`VENDOR_ID`), 
    KEY `IDX_VISIT_GROUP_VENDOR_ID_CONTACT_ID` (`VENDOR_ID`,`CONTACT_ID`), 
    KEY `IDX_VISIT_GROUP_ISP_ONLY_VENDOR_ID_CONTACT_ID` (`ISP_ONLY`,`VENDOR_ID`,`CONTACT_ID`), 
    KEY `IDX_VISIT_GROUP_TIME` (`TIME`), 
    KEY `IDX_VISIT_GROUP_EMAIL` (`EMAIL`), 
    KEY `IDX_VISIT_GROUP_CONTACT_ID` (`CONTACT_ID`), 
    CONSTRAINT `FK_VISIT_GROUP_VENDOR_ID` FOREIGN KEY (`VENDOR_ID`) REFERENCES `ADM_VENDOR` (`ID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci 

表ADM_CONTACT_OWNER:

CREATE TABLE `ADM_CONTACT_OWNER` (
    `ID` char(128) COLLATE utf8_polish_ci NOT NULL, 
    `VERSION` int(11) NOT NULL, 
    `CONTACT_ID` varchar(255) COLLATE utf8_polish_ci NOT NULL, 
    `OWNER_ID` varchar(255) COLLATE utf8_polish_ci NOT NULL, 
    `CREATED_ON` datetime NOT NULL, 
    `OWNERSHIP_RIGHTS` varchar(255) COLLATE utf8_polish_ci NOT NULL, 
    `GRANTED_BY_ID` varchar(255) COLLATE utf8_polish_ci NOT NULL, 
    `MODIFIED_ON` datetime NOT NULL, 
    `DELETED` tinyint(1) NOT NULL, 
    PRIMARY KEY (`ID`), 
    UNIQUE KEY `CONTACT_ID` (`CONTACT_ID`,`OWNER_ID`), 
    KEY `FK_CONTACT_OWNER_GRANTED_BY_ID` (`GRANTED_BY_ID`), 
    KEY `FK_CONTACT_OWNER_CONTACT_ID` (`CONTACT_ID`), 
    KEY `FK_CONTACT_OWNER_OWNER_ID` (`OWNER_ID`), 
    KEY `IDX_CONTACT_OWNER_CONTACT_OWNER` (`CONTACT_ID`,`OWNER_ID`), 
    KEY `IDX_CONTACT_OWNER_OWNER_DELETED` (`OWNER_ID`,`DELETED`), 
    CONSTRAINT `FK_CONTACT_OWNER_CONTACT_ID` FOREIGN KEY (`CONTACT_ID`) REFERENCES `ADM_CONTACT` (`ID`), 
    CONSTRAINT `FK_CONTACT_OWNER_GRANTED_BY_ID` FOREIGN KEY (`GRANTED_BY_ID`) REFERENCES `ADM_USER_ACCOUNT` (`ID`), 
    CONSTRAINT `FK_CONTACT_OWNER_OWNER_ID` FOREIGN KEY (`OWNER_ID`) REFERENCES `ADM_USER_ACCOUNT` (`ID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci 

全面查詢:

select 
visitgroup0_.VISIT_ID as col_0_0_, 
visitgroup0_.DURATION as col_1_0_, 
visitgroup0_.TIME as col_2_0_, 
visitgroup0_.VISIT_SOURCE as col_3_0_, 
visitgroup0_.VISIT_SOURCE_HOST as col_4_0_, 
visitgroup0_.VISIT_SOURCE_KEYWORDS as col_5_0_, 
visitgroup0_.EMAIL as col_6_0_, 
visitgroup0_.IP_ORGANIZATION as col_7_0_, 
visitgroup0_.CLIENT as col_8_0_, 
visitgroup0_.HOST as col_9_0_, 
visitgroup0_.IP as col_10_0_, 
visitgroup0_.LOCATION as col_11_0_, 
visitgroup0_.URI as col_12_0_, 
visitgroup0_.UUID as col_13_0_, 
visitgroup0_.VISIT_SCORE as col_14_0_, 
visitgroup0_.CONVERSATION as col_15_0_, 
visitgroup0_.CONTACT_ID as col_16_0_, 
visitgroup0_.CONVERSATION_ID as col_17_0_ 
from 
ADM_VISIT_GROUP visitgroup0_, 
ADM_CONTACT_OWNER contactown1_ 
where 
visitgroup0_.TIME>'2012-02-14 02:59:24' and 
visitgroup0_.VENDOR_ID='3739d7a7-2e8f-4409-bd2d-2b505b5e7749' and 
visitgroup0_.CONTACT_STATE='PROSPECT' and 
contactown1_.CONTACT_ID=visitgroup0_.CONTACT_ID and 
contactown1_.OWNER_ID='3f440a3e-a55e-44f5-ac75-d30bd27f4f97' 
order by visitgroup0_.TIME desc limit 30; 
使用

+----+-------------+--------------+--------+----------------------------------------------------------------------------------------------------------------------------------+----------------------+---------+------------------------------------------------+-------+--------------------------+ 
| id | select_type | table  | type | possible_keys                             | key     | key_len | ref           | rows | Extra     | 
+----+-------------+--------------+--------+----------------------------------------------------------------------------------------------------------------------------------+----------------------+---------+------------------------------------------------+-------+--------------------------+ 
| 1 | SIMPLE  | visitgroup0_ | range | FK_VISIT_GROUP_VENDOR_ID,IDX_VISIT_GROUP_VENDOR_ID_CONTACT_ID,IDX_VISIT_GROUP_TIME,IDX_VISIT_GROUP_CONTACT_ID     | IDX_VISIT_GROUP_TIME | 9  | NULL           | 19640 | Using where    | 
| 1 | SIMPLE  | contactown1_ | eq_ref | CONTACT_ID,FK_CONTACT_OWNER_CONTACT_ID,FK_CONTACT_OWNER_OWNER_ID,IDX_CONTACT_OWNER_CONTACT_OWNER,IDX_CONTACT_OWNER_OWNER_DELETED | CONTACT_ID   | 1534 | salesmanago_main.visitgroup0_.CONTACT_ID,const |  1 | Using where; Using index | 
+----+-------------+--------------+--------+----------------------------------------------------------------------------------------------------------------------------------+----------------------+---------+------------------------------------------------+-------+--------------------------+ 

ADM_VISIT_GROUP表中創建

任何人都可以幫助我提高查詢速度嗎?

+0

爲什麼完整查詢使用SM_ *表而編輯的使用ADM_ *? – vulkanino 2012-02-15 10:29:50

+0

錯字,對不起...我更新了帖子...我有兩個方案在本地 – Konrad 2012-02-15 10:45:32

+0

除了你不從'SM_CONTACT_OWNER'表中選擇數據,我沒有看到在查詢中的特殊問題,除了我會使用JOIN。 – vulkanino 2012-02-15 10:48:39

回答

1

它有手動過濾掉了很多,因爲MySQL只能夠按時使用索引(IDX_VISIT_GROUP_TIME)

因爲MySQL只能在查詢中使用每個表一個索引,嘗試進行行組合索引號:

VENDOR_ID 
CONTACT_STATE 
CONTACT_ID 
TIME 

列的順序在索引中很重要!如果所有子句都在查詢中,則只能從第一個子句到最後一個使用索引。而使用>或類似的東西很可能會使索引的其餘部分不可用。這就是爲什麼TIME是索引中的最後一個。

但是某個列沒有出現在你的where子句中,它不能到達TIME列的索引部分,並且索引效率低得多。這就是爲什麼在這種情況下,你會想創建一個單獨的索引與這些列。

+0

謝謝!剛剛5分鐘前做了。 19640行 - > 39!我覺得愚蠢 - 但也許這是因爲優化這個數據庫過去5天睡眠少於3小時/天:-) 我愛的計算器:) – Konrad 2012-02-15 11:03:23

0

我想:

  • 更改OWNER_IDVENDOR_IDVARCHARCONTACT_ID數據類型到UNSIGNED INTEGER或任何其他數值類型
  • 使用JOINADM_CONTACT_OWNER變化之間ADM_VISIT_GROUP
  • CONTACT_STATE是外國鍵爲STATE表或使用數字字段
  • 改善INDEX創建
+0

葉...改變整數接縫像長期解決方案,索引確實改善了這一點很多...謝謝... – Konrad 2012-02-15 12:01:18