mysql - 按 MYSQL 性能分组

标签 mysql

这是我要执行的查询。虽然它工作正常并提供了我需要的信息,但 GROUP BY 减慢了查询速度。

    SELECT
            activations.id,
            activations.product, 
            activations.transaction_date AS activation_date, 
            activations.control_number, 
            activations.retail AS plan, 
            activations.account_number, 
            activations.invoice_date AS act_inv_date, 
            activations.invoice_number AS act_inv, 
            activations.commission_status, 
            commission1.settlement_date AS commission1_date, 
            commission1.total AS commission1_credit, 
            commission1.invoice_date AS commission1_inv_date, 
            commission1.invoice_number AS commission1_inv,
            commission2.settlement_date AS commission2_date, 
            commission2.total AS commission2_credit, 
            commission2.invoice_date AS commission2_inv_date, 
            commission2.invoice_number AS commission2_inv,
            payment1.transaction_date AS payment1_date,
            payment1.retail AS payment1_retail, 
            payment1.cost AS payment1_cost, 
            payment1.commission AS payment1_commission, 
            payment1.account_number AS payment1_account, 
            payment1.invoice_date AS payment1_inv_date, 
            payment1.invoice_number AS payment1_inv,
            payment2.transaction_date AS payment2_date,
            payment2.retail AS payment2_retail, 
            payment2.cost AS payment2_cost, 
            payment2.commission AS payment2_commission, 
            payment2.account_number AS payment2_account, 
            payment2.invoice_date AS payment2_inv_date, 
            payment2.invoice_number AS payment2_inv,
            payment3.transaction_date AS payment3_date,
            payment3.retail AS payment3_retail, 
            payment3.cost AS payment3_cost, 
            payment3.commission AS payment3_commission, 
            payment3.account_number AS payment3_account, 
            payment3.invoice_date AS payment3_inv_date, 
            payment3.invoice_number AS payment3_inv,
            spiff1.invoice_number AS spiff1_inv,
            spiff1.total AS spiff1_credit, 
            spiff1.invoice_date AS spiff1_inv_date,
            spiff2.invoice_number AS spiff2_inv,
            spiff2.total AS spiff2_credit, 
            spiff2.invoice_date AS spiff2_inv_date,
            spiff3.invoice_number AS spiff3_inv,
            spiff3.total AS spiff3_credit, 
            spiff3.invoice_date AS spiff3_inv_date
        FROM
        `commissions_debits` AS activations
            LEFT OUTER JOIN
                commissions_credits AS commission1
            ON
                activations.control_number = commission1.control_number 
            AND 
                DATE(activations.transaction_date) = commission1.activation_date
            AND
                commission1.`type` = 'Commission'
            LEFT OUTER JOIN
                commissions_credits AS commission2
            ON
                activations.control_number = commission2.control_number 
            AND 
                DATE(activations.transaction_date) = commission2.activation_date
            AND
                commission2.id != commission1.id
            AND
                commission2.`type` = 'Commission'
            LEFT OUTER JOIN
                commissions_credits AS spiff1
            ON
                activations.control_number = spiff1.control_number
            AND 
                DATE(activations.transaction_date) = spiff1.activation_date     
            AND
                spiff1.`type` = 'Spiff'
            LEFT OUTER JOIN
                commissions_credits AS spiff2
            ON
                activations.control_number = spiff2.control_number
            AND 
                DATE(activations.transaction_date) = spiff2.activation_date     
            AND
                spiff2.`type` = 'Spiff'
            AND
                spiff2.id != spiff1.id
            LEFT OUTER JOIN
                commissions_credits AS spiff3
            ON
                activations.control_number = spiff3.control_number
            AND 
                DATE(activations.transaction_date) = spiff3.activation_date     
            AND
                spiff3.`type` = 'Spiff'
            AND
                spiff3.id != spiff2.id
            AND
                spiff3.id != spiff1.id
            LEFT OUTER JOIN 
                commissions_debits AS payment1
            ON 
                activations.control_number = payment1.control_number
            AND 
                payment1.`type` = 'Payment'
            LEFT OUTER JOIN 
                commissions_debits AS payment2
            ON 
                activations.control_number = payment2.control_number
            AND 
                payment2.`type` = 'Payment'
            AND
                payment2.id != payment1.id
            LEFT OUTER JOIN 
                commissions_debits AS payment3
            ON 
                activations.control_number = payment3.control_number
            AND 
                payment3.`type` = 'Payment'
            AND
                payment3.id != payment2.id
            AND
                payment3.id != payment1.id
        WHERE
            activations.`type` = 'Activation'
        AND
            activations.product != 'Simple SIM Act'
    GROUP BY
        activations.control_number
    ORDER BY
        activations.transaction_date

所以这得到了以下结果: 找到的行:46,780 警告:0 1 次查询的持续时间:9.431 秒

如果我将 GROUP BY 更改为 activations.transaction_date,它会减少到 4 秒,但是我会丢失一些有效行。

下面是两个表的创建:

CREATE TABLE `commissions_debits` (
        `id` INT(11) NOT NULL AUTO_INCREMENT,
        `settlement_date` DATE NOT NULL,
        `product` VARCHAR(300) NOT NULL COLLATE 'utf8_unicode_ci',
        `type` VARCHAR(100) NOT NULL COLLATE 'utf8_unicode_ci',
        `transaction_date` DATETIME NOT NULL,
        `control_number` VARCHAR(15) NOT NULL COLLATE 'utf8_unicode_ci',
        `retail` DECIMAL(9,2) NOT NULL,
        `discount` DECIMAL(9,4) NOT NULL,
        `cost` DECIMAL(9,2) NOT NULL,
        `commission` DECIMAL(9,2) NOT NULL,
        `account_number` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
        `invoice_date` DATE NOT NULL,
        `invoice_number` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
        `due_date` DATE NOT NULL,
        `commission_status` INT(11) NULL DEFAULT NULL,
        PRIMARY KEY (`id`),
        INDEX `account_number` (`account_number`),
        INDEX `type` (`type`),
        INDEX `product` (`product`(255)),
        INDEX `transaction_date` (`transaction_date`),
        INDEX `control_number` (`control_number`),
        INDEX `id_type` (`id`, `type`),
        INDEX `type_product_control` (`type`, `product`(255), `control_number`),
        INDEX `invoice_number` (`invoice_number`)
    )
    COLLATE='utf8_unicode_ci'
    ENGINE=InnoDB
    AUTO_INCREMENT=116672
    ;

    CREATE TABLE `commissions_credits` (
        `id` INT(11) NOT NULL AUTO_INCREMENT,
        `settlement_date` DATE NOT NULL,
        `activation_date` DATE NOT NULL,
        `type` VARCHAR(100) NOT NULL COLLATE 'utf8_unicode_ci',
        `item_description` VARCHAR(300) NOT NULL COLLATE 'utf8_unicode_ci',
        `control_number` VARCHAR(15) NOT NULL COLLATE 'utf8_unicode_ci',
        `dealer_code` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
        `debit` DECIMAL(9,2) NOT NULL,
        `credit` DECIMAL(9,2) NOT NULL,
        `tax` DECIMAL(9,2) NOT NULL,
        `total` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
        `account_number` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
        `invoice_date` DATE NOT NULL,
        `invoice_number` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
        `due_date` DATE NOT NULL,
        PRIMARY KEY (`id`),
        INDEX `dealer_code` (`dealer_code`),
        INDEX `account_number` (`account_number`),
        INDEX `type` (`type`),
        INDEX `control_number` (`control_number`),
        INDEX `date_type` (`activation_date`, `type`),
        INDEX `date_id_type` (`activation_date`, `id`, `type`),
        INDEX `invoice_number` (`invoice_number`)
    )
    COLLATE='utf8_unicode_ci'
    ENGINE=InnoDB
    AUTO_INCREMENT=72568
    ;

解释:

|| *id* || *select_type* || *table* || *type* || *possible_keys* || *key* || *key_len* || *ref* || *rows* || *Extra* ||
|| 1 || SIMPLE || activations || ref || type,product,type_product_control || type || 302 || const || 50997 || Using where; Using temporary; Using filesort ||
|| 1 || SIMPLE || commission1 || ref || type,control_number,date_type,date_id_type || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || commission2 || ref || type,control_number,date_type,date_id_type || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || spiff1 || ref || type,control_number,date_type,date_id_type || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || spiff2 || ref || type,control_number,date_type,date_id_type || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || spiff3 || ref || type,control_number,date_type,date_id_type || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || payment1 || ref || type,control_number,type_product_control || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || payment2 || ref || type,control_number,type_product_control || control_number || 47 || payst.activations.control_number || 1 ||  ||
|| 1 || SIMPLE || payment3 || ref || type,control_number,type_product_control || control_number || 47 || payst.activations.control_number || 1 ||  ||

也许我可以以某种方式改进指数?任何帮助将不胜感激。

最佳答案

如我所见,activations.control_number 没有索引。尝试为该列添加索引,然后请通知我负面或正面问题。

关于mysql - 按 MYSQL 性能分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31060336/

相关文章:

mysql - 使用npm mysql库时如何保护db?

python - Django mysql 准备语句

mysql - 如何在 MySQL 中将自动增量格式设置为 0001?

mysql - 如何返回特定列中仅存在重复项的行?

Mysql对面2在哪里

java - 用户 'admin' @'localhost' 的访问被拒绝(使用密码 : YES)

mysql - 连接表使值加倍

mysql - 我如何使用 Count 来计算每个玩家的行数

mysql - SQL - 在数字上使用嵌套替换

java - 如何有效编写 JPA 命名查询