私は2つのテーブルを持っており、それらの間の結合は永遠にかかります。関連するインデックスを作成しましたが、明らかに使われていないのは私の推測です。スロージョイン、インデックスが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 PKとしてTRADING_SYMBOL
とAS_ON_DATE
を有しています。 1つの日付に対して、この表には複数の取引記号が存在する可能性があります。
表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に関連するテーブルの両方でのインデックスのいずれかを使用して参照していけません。これはおそらくこれを遅らせる原因になります。
この理解は正しいと思いますが、取引記号に関連するインデックスを使用するように修正する方法です。これを使用するには取引記号に全文索引が必要ですか?ここで
EDITは、いくつかの追加の明確化です:
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
は、私は16ギガバイトのRAMを持って133.2 G
です。
追加インデックス 'INTRADAY_PRICES_CASH(SnapshotDate、TradingSymbol)'または 'ACTIVE_INSTRUMENTS_CASH(TRADING_SYMBOL、AS_ON_DATE)'が必要です。列の順序は重要であり、現在、2つの表の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キー I \t範囲\t IND_AS_ON_DATE、IND1、IND3、IND5 \t IND_AS_ON_DATE C \t REF \t IDX_SNAPSHOTDATE、IDX_SNAPSHOTDATETRADINGSYMBOL \t IDX_SNAPSHOTDATETRADINGSYMBOL – Kallol
あなたのテーブルに?これは、インデックスから完全に計算できる非常に簡単なクエリです。テーブルに10億行があっても36分かかることはありません。 'TradingSymbol'には10個以上の可能性の高い100文字が含まれていますか?シンボルを表すintで置き換えると、シンボルの平均長さに比べてスピードが向上します。 – Solarflare