大型mysql表的数据库性能索引

ulydmbyx  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(452)

希望你能允许我给你点建议,这样我就可以在这个过程中获得一些知识。我们有3个表-数据\产品,数据\发行人,数据\帐户余额

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;

数据发布者和数据产品中只有很少的100条记录,但是数据账户余额非常庞大,大约有15384358条记录。
制作的解释计划如下-


# id     select_type     table   partitions  type    possible_keys   key     key_len     ref     rows    filtered    Extra

1    SIMPLE  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    SIMPLE  data_accountbalance         ref    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

有人能帮助调整查询,使其不需要一个小时就可以运行吗?谢谢你给我的任何建议。

fxnxkyjh

fxnxkyjh1#

如果你的问题是你所展示的。。。那就是问题所在。它没有where子句。
这个查询实际上会返回15384358个结果。由于这两个较小的表是典型的域表,它们之间始终存在非空关系,因此它将为data\u accountbalance中的每一行返回1对1的结果。
实际的时间成本可能是在创建一个庞大的临时表(虽然我不确定)。只需下载整个数据库、所有3个表,您就可以优化temp table mysql config来加速这个过程,或者最好是这样,当您开始执行查询时,您可以在mysql准备好结果时读取结果(避免使用temp table)。或者,运行此查询的脚本可能试图将整个数据集读入内存,这需要很长时间?
下载所有数据有什么特别的原因吗?通常你只是下载你想要操作的数据。或者让mysql进行分组、求和等,然后根据所有数据返回您想要的答案。
您希望查询返回多少行?如果你想的东西少于1500万,那么答案就是添加某种where语句,或者一个聚合函数。根据您用来减少结果集的表和列,这些列必须被索引。
我希望这有帮助。:)

相关问题