每天晚上被删除的表上的 Mysql 索引

Posted

技术标签:

【中文标题】每天晚上被删除的表上的 Mysql 索引【英文标题】:Mysql Index on Table that gets deleted every night 【发布时间】:2021-04-18 10:13:11 【问题描述】:

我在 Amazon RDS 中使用 mysql。我有一张表booking,其结构如下:

CREATE TABLE `booking` (
   `id_by_customer` int(11) NOT NULL,
   `date` varchar(50) NOT NULL,
   `date_delivery` varchar(50) NOT NULL,
   `date_vat_effective` varchar(50) NOT NULL,
   `postingtext` varchar(50) NOT NULL,
   `amount` varchar(50) NOT NULL,
   `currency` varchar(50) NOT NULL,
   `vat` varchar(50) NOT NULL,
   `credit_type` varchar(50) NOT NULL,
   `debit_postingaccount_number` int(11) NOT NULL,
   `credit_postingaccount_number` int(11) NOT NULL,
   `tax_key` int(11) NOT NULL,
   `booking_number` double NOT NULL,
   `cost_location` varchar(50) NOT NULL,
   `circumstances_ll` varchar(50) NOT NULL,
   `transactions_purpose` varchar(150) NOT NULL,
   `receipts_assigned_invoice_numbers` varchar(50) NOT NULL,
   `receipts_assigned_counterparties` varchar(50) NOT NULL,
   `receipts_assigned_vat_rates` double NOT NULL,
   `receipts_assigned_assigned_amounts` varchar(50) NOT NULL,
   `receipts_assigned_assigned_dates` varchar(50) NOT NULL,
   `receipts_links` varchar(50) NOT NULL,
   `fixed` double NOT NULL,
   `comment` varchar(50) NOT NULL,
   `receipts_id_by_customer` varchar(50) NOT NULL,
   `transactions_id_by_customer` int(11) NOT NULL,
   PRIMARY KEY (`id_by_customer`),
   KEY `combined_index` (`debit_postingaccount_number`,`credit_type`,`credit_postingaccount_number`,`date`) USING BTREE
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1

该表的行数少于 100k。每天晚上我从表中删除所有条目并再次插入它们。我有一个运行 20 分钟以获得输出的当前查询。我想优化这个查询(我为此创建了视图 susa_list):

CREATE 
    ALGORITHM = UNDEFINED 
    DEFINER = `admin`@`%` 
    SQL SECURITY DEFINER
VIEW `susa_list` AS
    (SELECT 
        `bookingOuter`.`debit_postingaccount_number` AS `account_id`,
        YEAR(`bookingOuter`.`date`) AS `booking_year`,
        (SELECT 
                SUM(`booking`.`amount`)
            FROM
                `booking`
            WHERE
                ((`booking`.`credit_type` = 'H')
                    AND (`booking`.`debit_postingaccount_number` = `bookingOuter`.`debit_postingaccount_number`)
                    AND (YEAR(`booking`.`date`) = YEAR(`bookingOuter`.`date`)))) AS `DEBIT_H`,
        (SELECT 
                SUM(`booking`.`amount`)
            FROM
                `booking`
            WHERE
                ((`booking`.`credit_type` = 'S')
                    AND (`booking`.`debit_postingaccount_number` = `bookingOuter`.`debit_postingaccount_number`)
                    AND (YEAR(`booking`.`date`) = YEAR(`bookingOuter`.`date`)))) AS `DEBIT_S`,
        (SELECT 
                SUM(`booking`.`amount`)
            FROM
                `booking`
            WHERE
                ((`booking`.`credit_type` = 'H')
                    AND (`booking`.`credit_postingaccount_number` = `bookingOuter`.`debit_postingaccount_number`)
                    AND (YEAR(`booking`.`date`) = YEAR(`bookingOuter`.`date`)))) AS `CREDIT_H`,
        (SELECT 
                SUM(`booking`.`amount`)
            FROM
                `booking`
            WHERE
                ((`booking`.`credit_type` = 'S')
                    AND (`booking`.`credit_postingaccount_number` = `bookingOuter`.`debit_postingaccount_number`)
                    AND (YEAR(`booking`.`date`) = YEAR(`bookingOuter`.`date`)))) AS `CREDIT_S`
    FROM
        `booking` `bookingOuter`
    GROUP BY `bookingOuter`.`debit_postingaccount_number` , `booking_year`)

我的目标是加快查询速度

从 susa_list 中选择 *;

我应该每晚重建索引吗?数据只是夜夜变化一点点(索引列上的值没有变化)。

我之前尝试创建自己的表 susa_list_table 并运行

create table susa_list_table as select * from susa_list

每晚。然而,这个查询已经很慢了,而且我正在执行导入的 AWS Lambda (Python) 超时。

非常欢迎任何加快查询速度的建议! :-)

【问题讨论】:

请问你为什么要每天晚上删除并重新插入它们? Unclear -- 标题暗示从索引中删除(这是不可能的),文本谈到删除表的行。它提到了“重建索引”。请澄清。 【参考方案1】:

哎哟!

SUM(`booking`.`amount`)
`amount` varchar(50) NOT NULL,

请不要SUM VARCHARs;各种麻烦事都有可能发生。

而且,这些值可能是不同的货币吗?

此外,还有一个DATE 数据类型。 (还有DATETIMETIMESTAMP

`date` varchar(50) NOT NULL,
YEAR(`booking`.`date`)

我很惊讶该功能有效!

双?? booking_number double NOT NULL,

如果存在“千位分隔符”和“时区”等语言环境问题,请在插入表格之前处理

每天晚上我都会从表中删除所有条目并重新插入它们。

为什么??

请提供EXPLAIN SELECT ...。它可能表明没有使用复合索引。 可能有助于将credit_type 移动到该索引的开头。

在 MySQL 中,BTree 索引不会降级。不要重新索引。

VIEW 可能可以写成CASE,这样您就只能选择 1 次,而不是 5 次。

【讨论】:

以上是关于每天晚上被删除的表上的 Mysql 索引的主要内容,如果未能解决你的问题,请参考以下文章

超大表上的 MySQL 数据库性能选择

mysqldelete不用*

RDS 故障

临时表上的索引在表被删除的时候会被删除吗?

每次向表中添加数据时,我是不是应该删除并重新创建表上的索引?

mysql 索引作用范围