【问题标题】:Indexes for a large MYSQL table大型 MYSQL 表的索引
【发布时间】:2018-01-10 17:35:46
【问题描述】:

希望您能允许我挑选您的大脑,以便我在此过程中获得一些知识。 我们有 3 个表 - data_product、data_issuer、data_accountbalance

CREATE TABLE `data_issuer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`issuer_name` varchar(128) NOT NULL
PRIMARY KEY (`id`)
) ENGINE=InnoDB


CREATE TABLE `data_product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`issuer_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `data_product_name_issuer_id_260fec65_uniq` (`name`,`issuer_id`),
KEY `data_product_issuer_id_d07fa696_fk_data_issuer_id` (`issuer_id`),
CONSTRAINT `data_product_issuer_id_d07fa696_fk_data_issuer_id` FOREIGN KEY 
(`issuer_id`) REFERENCES `data_issuer` (`id`)
) ENGINE=InnoDB


CREATE TABLE `data_accountbalance` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
`nominee_name` varchar(128) NOT NULL,
`beneficiary_name` varchar(128) NOT NULL,
`nominee_id` varchar(128) NOT NULL,
`account_id` varchar(16) NOT NULL,
`product_id` int(11) NOT NULL,
`register_id` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `data_accountbalance_date_product_id_nominee__7b8d2c6a_uniq` (`date`,`product_id`,`nominee_id`,`beneficiary_name`),
 KEY `data_accountbalance_product_id_nominee_id_date_8ef8754f_idx` (`product_id`,`nominee_id`,`date`),
 KEY `data_accountbalance_register_id_4e78ec16_fk_data_register_id` (`register_id`),
 KEY `data_accountbalance_product_id_date_nominee_i_c3a41e39_idx` (`product_id`,`date`,`nominee_id`,`beneficiary_name`,`balance_amount`),
 CONSTRAINT `data_accountbalance_product_id_acfb18f6_fk_data_product_id` FOREIGN KEY (`product_id`) REFERENCES `data_product` (`id`),
 CONSTRAINT `data_accountbalance_register_id_4e78ec16_fk_data_register_id` FOREIGN KEY (`register_id`) REFERENCES `data_register` (`id`)
 ) ENGINE=InnoDB

运行下面的查询时,系统大约需要一个小时才能响应 -

SELECT SQL_NO_CACHE *
from data_product
INNER JOIN `data_issuer` ON (`data_issuer`.`id` = `data_product`.`issuer_id`)
INNER JOIN `data_accountbalance` ON (`data_accountbalance`.`product_id` = `data_product`.`id`)
LIMIT 100000000;

data_issuer 和 data_product 都只有几条 100 条记录,但 data_accountbalance 很大,大约有 15,384,358 条记录。

产生的解释计划如下 -

# id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 简单的 data_product ALL PRIMARY,data_product_issuer_id_d07fa696_fk_data_issuer_id 459 100 1 SIMPLE data_issuer eq_ref PRIMARY PRIMARY 4 pnl.data_product.issuer_id 1 100 1 简单的 data_accountbalance 参考 data_accountbalance_product_id_nominee_id_date_8ef8754f_idx,data_accountbalance_product_id_date_nominee_i_c3a41e39_idx data_accountbalance_product_id_date_nominee_i_c3a41e39_idx 4 pnl.data_product.id 493 100

有人可以帮助调整查询,使其不需要一个小时即可运行吗?感谢您对我的任何指点。

【问题讨论】:

  • 我认为如果您在 data_accountbalance.product_id` 列上创建索引,它将被优化
  • @Rams - 我尝试了你的建议,但恐怕没有喜悦。查询仍然需要相同的时间。
  • 返回多少行?
  • @RickJames - 查询返回 15,402,355 行
  • @Gayathri - 你将如何处理这么多数据?它会扼杀客户吗?您需要多次运行它吗?如果是这样,为什么?也许有一些方法可以解决真正的目标,而无需重复运行长达一小时的查询。

标签: mysql database-performance query-tuning


【解决方案1】:

如果您的查询实际上就是您在此处显示的内容...那么这就是问题所在。它没有 WHERE 子句。

该查询实际上将返回 15,384,358 个结果。由于这两个较小的表是典型的域表,并且一直存在 NOT NULL 关系,因此它将为 data_accountbalance 中的每一行返回 1 到 1 个结果。

实际的时间成本可能是创建一个大规模临时表(虽然我不确定)。只需下载整个数据库,所有 3 个表,您可以考虑优化您的临时表 MySQL 配置以可能加快速度,或者最好使其在开始执行查询时可以读取结果,因为 MySQL 已准备好它们(避免临时表)。或者,也许您运行此查询的脚本正在尝试将整个数据集读入内存,这需要很长时间?

下载所有数据是否有特殊原因?通常你只需下载你想要操作的数据。或者让 MySQL 进行分组、求和等,然后根据所有数据返回您想要的答案。

您希望查询返回多少行?如果你想的东西少于 1500 万,那么答案是添加某种 WHERE 语句或聚合函数。根据您用于减少结果集的表和列,必须对这些列进行索引。

我希望这会有所帮助。 :)

【讨论】:

  • 感谢戴夫的想法。该查询是 Tableau 报告的摘录,并且按原样(无 WHERE)。不幸的是,我需要优化它。关于如何做到这一点的任何其他想法?
  • 是的,如果您正在运行报告,最终目标是浓缩大量数据,经过整理和汇总后,形成少量可供人类消化的数据。例如。您想查看每个数据发行者 (GROUP BY data_issuer.id) 或按产品和月份 (GROUP BY data_product.id, DATE_FORMAT('%Y-%m', data_accountbalance.date)) 的提名人数。关键是您希望 MySQL 在将数据发送到报告软件之前进行数据处理。这只是意味着您的报告软件仅使用 MySQL 作为数据保存,而不使用它的查询能力。这有帮助吗?
  • 您确定延迟时间是 MySQL 返回数据,而不是您的 Tableau 报告软件解析和处理那么多数据吗?
  • Tableau 允许企业以不同的方式汇总和分析数据。业务部门无需每次都来找我们,而是简单地使用摘录并执行各种摘要,这是 Tableau 的主要优势之一。我们的工作就是为他们提供不同的提取物。是的,延迟是在业务团队进行任何总结之前运行摘录
  • 我曾与其他报告软件 (CrystalReports) 合作,它在幕后添加 WHERE 和 GROUP BY 子句,以便数据库服务器完成繁重的工作。也许您可以将 Tableau 配置为也执行此操作?否则,下一个要看的地方可能是带宽。您是否能够看到在那一小时内传输了多少数据,以及这些表的总数据大小?也许加快从 DB 到 Tableau 的连接会有所帮助?但是,如果您可以从网络中看到直到该小时延迟结束之前没有发送任何内容,那么这不是问题。
猜你喜欢
  • 2014-04-07
  • 1970-01-01
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 2014-09-04
相关资源
最近更新 更多