0

我有两张桌子,它们之间的连接需要永远。创建了相关索引,但显然它没有被使用是我的猜测。

表格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_SYMBOLAS_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 内存。

4

1 回答 1

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'

注意 how key_lenis only 3,暗示它只使用DATE索引的一部分。

使用相同CHARACTER SETand和。(建议您也将它们拼写相同。)不同的排序规则会阻止使用索引(对于该列)。COLLATIONTRADING_SYMBOLTradingSymbol

这不是给你同样的COUNT(*)吗?

SELECT  COUNT(*)
    FROM  INTRADAY_PRICES_CASH
    WHERE  p.`SnapshotDate`>'2017-08-14';

如果您从 15 日开始,为什么不说>= ... 15而不是> ... 14?这将适用DATETIMEDATE.

其他桌子使用INSTRUMENT_ID吗?或者可以删除该列并将UNIQUE密钥提升到PRIMARY

如果您确实需要加入,那么我可能有其他索引建议。

于 2017-08-26T01:18:32.650 回答