我有两个表,它们之间的连接需要永远。创建相关索引,但显然它没有被使用是我的猜测。
表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内存。
答案 0 :(得分:0)
请选择更好的别名 - 两个表都有初始C和I.
请使用首选的JOIN...ON
。
SELECT COUNT(*)
FROM INTRADAY_PRICES_CASH AS p
JOIN ACTIVE_INSTRUMENTS_CASH AS a
ON a.`TRADING_SYMBOL` = p.`TradingSymbol`
AND a.`AS_ON_DATE` = p.`SnapshotDate`
WHERE p.`SnapshotDate`>'2017-08-14'
请注意key_len
仅为3,暗示它仅使用索引的DATE
部分。
对CHARACTER SET
和COLLATION
使用相同的 TRADING_SYMBOL
和TradingSymbol
。 (建议你拼写它们也一样。)不同的排序规则会阻止使用索引(对于那一列)。
这不会给你相同的COUNT(*)
吗?
SELECT COUNT(*)
FROM INTRADAY_PRICES_CASH
WHERE p.`SnapshotDate`>'2017-08-14';
如果您从15日开始,为什么不说>= ... 15
而不是> ... 14
?这适用于DATETIME
以及DATE
。
其他一些表是否使用INSTRUMENT_ID
?或者可以删除该列并将UNIQUE
密钥提升为PRIMARY
?
如果您确实需要加入,那么我可能会有其他索引建议。