【问题标题】:speed up views in MySQL加速 MySQL 中的视图
【发布时间】:2015-06-12 03:54:36
【问题描述】:

以下视图包含 2000 行(不多),但获取值大约需要 4 秒。

CREATE 
ALGORITHM = UNDEFINED 
DEFINER = `root`@`localhost` 
SQL SECURITY DEFINER
VIEW `saving_account_ledger_view_new1` AS
SELECT 
    (CASE
        WHEN
            ((`mt`.`Tr_Type` = 'DJV')
                OR (`mt`.`Tr_Type` = 'DCA')
                OR (`mt`.`Tr_Type` = 'DBK'))
        THEN
            'Deposit'
        ELSE (CASE
            WHEN
                ((`mt`.`Tr_Type` = 'WJV')
                    OR (`mt`.`Tr_Type` = 'WCA')
                    OR (`mt`.`Tr_Type` = 'WBK'))
            THEN
                'Withdraw'
        END)
    END) AS `Particulars`,
    `mt`.`SBAc_No` AS `SBAc_No`,
    `mt`.`Tr_Date` AS `Tr_Date`,
    `mt`.`Tr_No` AS `Tr_No`,
    SUM((CASE
        WHEN (`mt`.`Tr_Type` = 'DCA') THEN `mt`.`Pri_Amt`
        WHEN (`mt`.`Tr_Type` = 'DJV') THEN `mt`.`Pri_Amt`
        WHEN (`mt`.`Tr_Type` = 'DBK') THEN `mt`.`Pri_Amt`
        ELSE 0
    END)) AS `Deposit`,
    SUM((CASE
        WHEN (`mt`.`Tr_Type` = 'WCA') THEN `mt`.`Pri_Amt`
        WHEN (`mt`.`Tr_Type` = 'WJV') THEN `mt`.`Pri_Amt`
        WHEN (`mt`.`Tr_Type` = 'WBK') THEN `mt`.`Pri_Amt`
        ELSE 0
    END)) AS `Withdraw`,
    (IFNULL((SELECT 
                    SUM((CASE
                            WHEN
                                ((`mt2`.`Tr_Type` = 'DJV')
                                    OR (`mt2`.`Tr_Type` = 'DCA')
                                    OR (`mt2`.`Tr_Type` = 'DBK'))
                            THEN
                                `mt2`.`Pri_Amt`
                            ELSE 0
                        END))
                FROM
                    `sb_loan_trans` `mt2`
                WHERE
                    ((`mt2`.`Tr_Date` <= `mt`.`Tr_Date`)
                        AND (`mt2`.`SBAc_No` = `mt`.`SBAc_No`)
                        AND (`mt2`.`Tr_No` < `mt`.`Tr_No`))),
            0) - IFNULL((SELECT 
                    SUM((CASE
                            WHEN
                                ((`mt2`.`Tr_Type` = 'WJV')
                                    OR (`mt2`.`Tr_Type` = 'WCA')
                                    OR (`mt2`.`Tr_Type` = 'WBK'))
                            THEN
                                `mt2`.`Pri_Amt`
                            ELSE 0
                        END))
                FROM
                    `sb_loan_trans` `mt2`
                WHERE
                    ((`mt2`.`Tr_Date` <= `mt`.`Tr_Date`)
                        AND (`mt2`.`SBAc_No` = `mt`.`SBAc_No`)
                        AND (`mt2`.`Tr_No` < `mt`.`Tr_No`))),
            0)) AS `Balance`
FROM
    `sb_loan_trans` `mt`
GROUP BY `mt`.`Tr_Date` , `mt`.`Tr_No` , `mt`.`SBAc_No` , `mt`.`Tr_Type`

表结构如下:-

CREATE TABLE `sb_loan_trans` (
`Tr_No` bigint(20) NOT NULL,
`SBAc_No` bigint(20) NOT NULL,
`Tr_Date` datetime NOT NULL,
`Tr_Type` char(10) NOT NULL,
`Pri_Amt` double NOT NULL,
`Int_Amt` double NOT NULL DEFAULT '0',
`Penal_Int_Amt` double NOT NULL DEFAULT '0',
`FA_Pri` bigint(20) NOT NULL DEFAULT '0',
`FA_Int` bigint(20) NOT NULL DEFAULT '0',
`Fa_Penal_Int` bigint(20) NOT NULL DEFAULT '0',
`Recept_No` varchar(10) DEFAULT '0',
`Disurb_Code` int(11) DEFAULT '0',
`CREATEDID` char(10) DEFAULT NULL,
`CREATEDDATETIME` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`UPDATEDID` char(10) DEFAULT NULL,
`UPDATEDDATETIME` datetime DEFAULT NULL,
PRIMARY KEY (`Tr_No`),
KEY `IDX_SB_LN1` (`Tr_Date`,`Tr_No`,`SBAc_No`,`Tr_Type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

由于上述视图被频繁使用,应用程序的速度受到极大影响。有什么办法可以加快它的性能?

【问题讨论】:

  • 请为使用SELECTSELECT 和视图内的SELECT 提供EXPLAIN SELECT ...;
  • 通过表扫描应用SELECT COUNT(*) FROM saving_account_ledger_view_new1; _Probably_ that many rows are put into a tmp table with no indexes, then the WHERE` 子句的值是多少。
  • innodb_buffer_pool_size 的值是多少?有多少 RAM 可用?

标签: mysql performance view


【解决方案1】:

什么是物化视图?物化视图(MV)是 查询的预计算(具体化)结果。不同于简单的 VIEW 物化视图的结果存储在某处,通常在 桌子。需要立即响应时使用物化视图 以及物化视图所基于的查询需要很长时间 产生一个结果。物化视图必须刷新一次 尽管。这取决于具体化视图的频率要求 刷新以及它的内容有多真实。基本上是一个物化视图 可以立即刷新或延迟刷新,可以完全刷新或 到某个时间点。 MySQL 不提供物化视图 通过它自己。但是自己构建物化视图很容易。

在这里查看更多 http://www.fromdual.com/mysql-materialized-views

虽然这就是你想要阅读的内容

【讨论】:

  • 好埃里克。感谢分享。在金融应用中,我会说永远不会。可能是陈旧的数据,例如 stackoverflow 上的标签和问题计数,是的
  • 再一次,也许你的想法是个好主意,在宏伟的计划中,行相对较少。 MV 在任何新行插入时都会刷新(注意财务应用程序会反转条目而不是更新)。所以一个锁表调用。插入。刷新mv。开锁。频繁读取的消费者也会获得锁。我的问题是是否有正当理由返回前端的所有行,或者可以使用 where 子句对其进行优化
  • 在使用 InnoDB 时几乎总是不应该“锁定表”。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多