我有兩個表,它們之間的連接需要永久。創建了相關索引,但顯然沒有被使用是我的猜測。慢連接,索引沒有在varchar列上使用
表1:
CREATE TABLE `INTRADAY_PRICES_CASH` (
`TradingSymbol` varchar(100) CHARACTER SET latin1 NOT NULL,
`SnapshotDateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
`Open` double NOT NULL,
`Low` double NOT NULL,
`High` double NOT NULL,
`Close` double NOT NULL,
`Volume` double NOT NULL,
`SnapshotDate` date NOT NULL,
`SnapshotTime` time NOT NULL,
`UpdateToDBTime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`TradingSymbol`,`SnapshotDateTime`),
KEY `IDX_SNAPSHOTDATE` (`SnapshotDate`),
KEY `IDX_SNAPSHOTDATETIME` (`SnapshotDateTime`),
KEY `IDX_SNAPSHOTTIME` (`SnapshotTime`),
KEY `IDX_TRADINGSYMBOL` (`TradingSymbol`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
表2:
CREATE TABLE `ACTIVE_INSTRUMENTS_CASH` (
`INSTRUMENT_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`INSTRUMENT_TOKEN` bigint(20) DEFAULT NULL,
`EXCHANGE_TOKEN` bigint(20) DEFAULT NULL,
`TRADING_SYMBOL` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`INSTRUMENT_NAME` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
`EXPIRY` date DEFAULT NULL,
`LOT_SIZE` double DEFAULT NULL,
`TICK_SIZE` float DEFAULT NULL,
`INSTRUMENT_TYPE` varbinary(10) DEFAULT NULL,
`SEGMENT` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`EXCHANGE` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`AS_ON_DATE` date NOT NULL,
PRIMARY KEY (`INSTRUMENT_ID`),
UNIQUE KEY `IND_AS_ON_DATE` (`AS_ON_DATE`,`TRADING_SYMBOL`),
KEY `IND1` (`AS_ON_DATE`),
KEY `IND2` (`INSTRUMENT_TOKEN`),
KEY `IND3` (`TRADING_SYMBOL`),
KEY `IND4` (`INSTRUMENT_TYPE`)
) ENGINE=InnoDB AUTO_INCREMENT=196606 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
表2具有TRADING_SYMBOL
和AS_ON_DATE
作爲PK。對於一個日期,此表中可能有多個交易符號。
在表1中,對於相同的交易符號和日期組合,我們將有多行代表同一日期不同分鐘的各種價格。
現在,我想加入這些表以瞭解在兩個表中有多少行與交易符號和日期組合匹配。
SELECT COUNT(*) FROM INTRADAY_PRICES_CASH C, ACTIVE_INSTRUMENTS_CASH I
WHERE C.`SnapshotDate`>'2017-08-14'
AND I.`TRADING_SYMBOL`=C.`TradingSymbol`
AND I.`AS_ON_DATE`=C.`SnapshotDate`
解釋表明,它是使用:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE I range IND_AS_ON_DATE,IND1,IND3 IND_AS_ON_DATE 3 \N 15066 Using where; Using index
1 SIMPLE C ref IDX_SNAPSHOTDATE IDX_SNAPSHOTDATE 3 u754793479_stock.I.AS_ON_DATE 771 Using where; Using index
奇怪的是,我不使用它任何指數的兩個有關TradingSymbol表見。這可能會導致延遲。
理解是否正確,如果是,如何糾正,以便使用與交易符號有關的指數。我是否需要在交易代碼上使用全文索引才能使用它。
編輯
這裏有一些補充說明:
INTRADAY_PRICES_CASH
含有69700675點的行。 ACTIVE_INSTRUMENTS_CASH
包含190177行。
SELECT COUNT(*) FROM INTRADAY_PRICES_CASH C WHERE C.SnapshotDate>'2017-08-14'
回報3911679行
我的主機供應商沒有提供給innodb_index_stats訪問。因此,不能點火此查詢: SELECT *, stat_value * @@innodb_page_size FROM mysql.innodb_index_stats WHERE table_name = 'INTRADAY_PRICES_CASH' and stat_name = 'size' and indexname = 'IDX_SNAPSHOTDATETRADINGSYMBOL';
select @@innodb_buffer_pool_size
爲133.2 g^
我有16GB的RAM。
您需要附加索引'INTRADAY_PRICES_CASH(SnapshotDate,TradingSymbol)'或'ACTIVE_INSTRUMENTS_CASH(TRADING_SYMBOL,AS_ON_DATE)'。列的順序很重要,而且您的兩個表中的2列索引目前有所不同。 – Solarflare
謝謝。新增了兩個。雖然解釋顯示它使用INTRADAY_PRICES_CASH(SnapshotDate,TradingSymbol),但仍需要36分鐘。這些是索引:'KEY' IND5'('TRADING_SYMBOL','AS_ON_DATE')''和'KEY' IDX_SNAPSHOTDATETRADINGSYMBOL'('SnapshotDate','TradingSymbol')'。說明正顯示出:表\t型\t possible_keys \t關鍵 我\t範圍\t IND_AS_ON_DATE,IND1,IND3,IND5 \t IND_AS_ON_DATE Ç\t裁判\t IDX_SNAPSHOTDATE,IDX_SNAPSHOTDATETRADINGSYMBOL \t IDX_SNAPSHOTDATETRADINGSYMBOL – Kallol
什麼是你所得到的數量和多少行你有在你的桌子上?這是一個非常簡單的查詢,可以從索引中完全計算,即使您的表中有十億行,也不需要36分鐘。 「TradingSymbol」包含/含有更多可能包含10個或更多可能100個字符的內容?用代表該符號的int代替它可以提高速度(相對於符號的平均長度)。 – Solarflare