Mysql

MySQL選擇查詢不使用必需索引

  • December 20, 2019

我有一個有 200 萬條記錄且沒有主鍵或唯一鍵的表。我添加了兩個索引,並且希望將一個索引用於我的選擇查詢。

當我看到解釋計劃時,優化器沒有使用我創建的任何索引。

我正在查詢更廣泛的數據,根據我現有的案例,我無法減少這些數據,我希望優化器選擇索引。

我不想使用 FORCE INDEX 子句,我想知道如何讓優化器使用 INDEXS

下面是表 SCHEMA

CREATE TABLE EVENT_DETAILS
(
 ORG_ID CHAR(32) NOT NULL,
 CONFIG_KEY CHAR(32) NOT NULL,
 COMPONENT_NAME VARCHAR(512) NOT NULL,
 REQUEST_ID  CHAR(32) NOT NULL,
 UPDATE_DATE INT NOT NULL,
 UPDATE_TIME INT NOT NULL,
 CLIENT CHAR(16) NOT NULL,
 STATUS INT NOT NULL,
 EVENT_DATA VARCHAR(1024),
 MESSAGE VARCHAR(512),
 INSERTED_TIME     TIMESTAMP      DEFAULT CURRENT_TIMESTAMP NOT NULL
);


CREATE TABLE DOMAIN_KEYS (
 DOMAIN_KEY char(32) COLLATE utf8_unicode_ci NOT NULL,
 DOMAIN_IDENTITY varchar(256) COLLATE utf8_unicode_ci NOT NULL,
 DOMAIN_DISPLAY_NAME varchar(256) COLLATE utf8_unicode_ci NOT NULL,
 ORG_ID char(32) COLLATE utf8_unicode_ci NOT NULL,
 LOCATION_KEY int(11) DEFAULT '0',
 DESCRIPTION varchar(4000) COLLATE utf8_unicode_ci DEFAULT NULL,
 CATEGORY int(11) NOT NULL DEFAULT '1',
 ENVIRONMENT_TYPE int(11) NOT NULL DEFAULT '0',
 PRIMARY KEY (DOMAIN_KEY)
);

CREATE TABLE ORGANISATIONS (
 ORG_ID char(32) NOT NULL,
 ORG_IDENTITY varchar(256) NOT NULL,
 ORG_NAME varchar(256) NOT NULL,
 ORG_DESC varchar(256) DEFAULT NULL,
 PARENT_ORG_ID char(32) NOT NULL,
 PRIMARY KEY (ORG_ID)
);

以下是創建的索引

CREATE INDEX MYINDEX1 ON EVENT_DETAILS (ORG_ID,CONFIG_KEY,COMPONENT_NAME,UPDATE_DATE);
CREATE INDEX MYINDEX2 ON EVENT_DETAILS (UPDATE_DATE,COMPONENT_NAME);

下面是查詢

SELECT ED.ORG_ID, 
      ORG.ORG_IDENTITY, 
      ORG.ORG_NAME, 
      ED.CONFIG_KEY, 
      REPLACE(REPLACE(ED.COMPONENT_NAME,'-CURRENT',''),'-HISTORICAL','') AS COMP_NAME,
      DO.DOMAIN_IDENTITY,
      DO.DOMAIN_DISPLAY_NAME,
      GROUP_CONCAT(ED.STATUS ORDER BY ED.INSERTED_TIME DESC) AS ALL_STATUS 
FROM EVENT_DETAILS ED , 
    ORGANISATIONS ORG , 
    DOMAIN_KEYS DO   
WHERE UPDATE_DATE > '20191205' 
 AND ORG.ORG_ID = ED.ORG_ID 
 AND DO.DOMAIN_KEY=ED.CONFIG_KEY 
 AND DO.LOCATION_KEY <> 0 
GROUP BY ED.ORG_ID,
     ORG.ORG_IDENTITY, 
     ORG.ORG_NAME, 
     ED.CONFIG_KEY,
     DO.DOMAIN_IDENTITY,
     DO.DOMAIN_DISPLAY_NAME,
     COMP_NAME 
HAVING ALL_STATUS LIKE '0,0,0%';

在此處輸入圖像描述

我也想減少創建的臨時表,因為我觀察到當查詢正在執行大量數據時,我的數據庫機器的免費本地儲存會下降

有人請建議所需的架構更改以及是否可以優化查詢。

查詢執行中斷

在此處輸入圖像描述

  • 使用 InnoDB。
  • PRIMARY KEY每張桌子上都有一個
  • 不要盲目使用VARCHAR(256)find一個合理的限制。
  • 使用JOIN .. ON語法,而不是 commalist 語法。
  • 使用DATETIME而不是一對INTs
  • CHAR(32)聞起來像某種雜湊 - 這對於索引和JOINing.
  • 如果這些是十六進製字元串,請使用CHARACTER SET ascii,而不是 utf8。
  • HEX使用和UNHEX和可以使散列更小BINARY(16)
  • 如果超過 20% 的 ED 滿足UPDATE_DATE > '20191205',優化器將避開從該列開始的索引進行表掃描。

MySQL每次查詢每個表只使用一個索引,在復合索引上它將使用從左到右的列,where子句需要以相同的順序指定列。我會嘗試在 ED 上創建一個涵蓋 ORG_ID 和 UPDATE_DATE 的索引,更改列的順序,以便最有選擇性的過濾器首先出現。

引用自:https://dba.stackexchange.com/questions/255955