【问题标题】:How to optimize a large mysql table (stock data)如何优化大型mysql表(股票数据)
【发布时间】:2018-08-06 10:11:20
【问题描述】:

我有一个具有以下结构的表,

    `trading_daily_price` (
    `id` int(11) NOT NULL PRAMARY AUTO_INCREMENT,
    `date` date DEFAULT NULL,
    `Symbol` varchar(20) DEFAULT NULL,
    `Market` varchar(12) DEFAULT NULL,
    `QuoteName` text,
    `Price` float DEFAULT NULL,
    `PriceChange` float DEFAULT NULL,
    `PriceChangePct` float DEFAULT NULL,
    `Volume` float DEFAULT NULL,
    `DayLow` float DEFAULT NULL,
    `DayHigh` float DEFAULT NULL,
    `Week52Low` float DEFAULT NULL,
    `Week52High` float DEFAULT NULL,
    `Open` float DEFAULT NULL,
    `High` float DEFAULT NULL,
    `Bid` float DEFAULT NULL,
    `BidSize` float DEFAULT NULL,
    `Beta` float DEFAULT NULL,
    `PrevClose` float DEFAULT NULL,
    `Low` float DEFAULT NULL,
    `Ask` float DEFAULT NULL,
    `AskSize` float DEFAULT NULL,
    `VWAP` float DEFAULT NULL,
    `Yield` float DEFAULT NULL,
    `Dividend` char(12) DEFAULT NULL,
    `DivFrequency` varchar(24) DEFAULT NULL,
    `SharesOut` float DEFAULT NULL,
    `PERatio` float DEFAULT NULL,
    `EPS` float DEFAULT NULL,
    `ExDivDate` date DEFAULT NULL,
    `MarketCap` float DEFAULT NULL,
    `PBRatio` float DEFAULT NULL,
    `Exchange` varchar(32) DEFAULT NULL,
    `NewsTitle` varchar(1024) DEFAULT NULL,
    `NewsSource` varchar(32) DEFAULT NULL,
    `NewsPublicationDate` date DEFAULT NULL,
    `NewsURL` varchar(256) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我没有找到分解它的想法,在前端演示中,我需要显示所有这些列。我正在写一个类似的查询,

    SELECT * FROM trading_daily_price WHERE date='SOME_DATE' AND Symbol='%search_key%' ORDER BY 'column' LIMIT 10

该表有数百万条记录,并且每天都会添加新记录。现在的问题是每个查询都需要花费大量时间来生成输出。在带有 DigitalOcean 的 4GB VPS 和一些配置中,它运行良好。但是,在 Godaddy 业务托管中,它的运行速度非常缓慢。

我想知道将列分成多个表并使用 JOIN 语句是否更好。它会提高性能吗?或者我需要遵循其他优化逻辑。

按照 Madhur 的建议,我已将 INDEX 添加到日期、符号和市场。它提高了上面的查询速度,但是下面的查询仍然需要很多时间。

    SELECT `date`,`Price` FROM trading_daily_price WHERE `Symbol` = 'GNCP:US' ORDER BY date ASC

提前致谢, 拉吉布

【问题讨论】:

  • 在日期、符号和“列”列上应用索引。
  • 非常感谢,现在速度确实提高了,不过还是有一个问题,建议还是不破表?
  • 您正在执行SELECT *,因此将表分成多个表肯定不会导致更快的读取速度。此外,您的表是trading daily price,所有这些似乎都是该对象的合理属性,因此没有必要对其进行规范化。
  • 谢谢,这是我想但不确定的重点。我还认为如果我使用多个表,那么多个 JOINING 操作可能会给服务器带来额外的负载。

标签: mysql query-optimization stock-data


【解决方案1】:

按照 Madhur 和 JNevill 的建议,我发现唯一的解决方案是根据需要创建多个 INDEX。

对于第一个 SQL,

    SELECT * FROM trading_daily_price WHERE date='SOME_DATE' AND Symbol='%search_key%' ORDER BY 'column' LIMIT 10

我们需要如下创建索引,

    CREATE INDEX index_DCS ON trading_daily_price (`date`,column, symbol); 

对于第二个 SQL,

    SELECT `date`,`Price` FROM trading_daily_price WHERE `Symbol` = 'GNCP:US' ORDER BY date ASC

我们需要如下创建索引,

    CREATE INDEX index_DPS ON trading_daily_price (`date`,Price, symbol); 

谢谢

【讨论】:

    【解决方案2】:

    您的第一次查询不需要日期、符号和列索引,因为您正在按 %text% 搜索符号,而 MySql 只能使用索引的日期部分。带有日期和列的索引应该更好,因为 MySQL 可以利用索引中的两列

    对于您的新查询,您将需要符号、日期和价格的索引。通过这个索引,您的查询不需要返回到数据的聚集索引。

    是否拆分表取决于您的用例:您将如何处理旧数据。如果旧数据不会被频繁访问,可以考虑拆分。但是您的应用程序需要满足它。

    【讨论】:

      【解决方案3】:

      拆分那张桌子。

      一张表有开盘/最高/最低/收盘/成交量,按股票和日期索引。

      另一个表格提供了关于每只股票的静态信息。

      也许另一个人有从原始数据中得出的统计数据。

      做出类似的改变,然后回来寻求更多建议/滥用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-05
        • 2018-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        相关资源
        最近更新 更多