mysql - 如何从此查询中消除 "Out of Memory Exception"?

标签 mysql sql optimization

我收到“内存不足”异常,并且我已经没有关于如何执行此操作的想法了。

我有下表:

create table CGNS
(
CHANNEL SMALLINT NOT NULL,
PNL_DATE     TIMESTAMP NOT NULL,
CHANNEL_NAME VARCHAR(200) NOT NULL,
PRODUCT_LINE  CHAR(10) NOT NULL,
PRODUCT_LINE_NAME VARCHAR(100) NOT NULL,
ACCOUNT CHAR(5) NOT NULL,
ACCOUNT_NAME VARCHAR(100) NOT NULL,
AMOUNT NUMERIC(20, 6) NOT NULL
)

create table CP
(
MARKETPLACE_ID NUMERIC(38, 0) NOT NULL,
CHANNEL     SMALLINT NOT NULL,
SHIP_MONTH  DATE NOT NULL,
GL_PRODUCT_GROUP NUMERIC(4, 0) NOT NULL,
PRODUCT_CATEGORY VARCHAR(100) NULL,
PRODUCT_SUBCATEGORY VARCHAR(100) NULL,
PRIME_PLAN  CHAR(10) NULL,
ITEM_SIZE VARCHAR(10) NULL,
CP_COMPONENT  VARCHAR(100) NOT NULL,
AMOUNT  NUMERIC(20, 6) NOT NULL
)

create table ACCOUNT_MAPPER
(
CGNS_ACCOUNT   CHAR(5) NOT NULL,
CP_COMPONENT   VARCHAR(100) NOT NULL
)

create table CHANNEL_MAPPER
(
CGNS_CHANNEL   SMALLINT NOT NULL,
CP_MARKETPLACE_ID  NUMERIC(38, 0) NOT NULL,
CP_CHANNEL  SMALLINT NOT NULL   
)

Create table PRODUCT_LINE_MAPPER
(
CGNS_PRODUCT_LINE   CHAR(10) NOT NULL,
CP_GL_PRODUCT_GROUP NUMERIC(4, 0) NOT NULL
)

我想使用以下查询将数据生成到表 SLICED 中,如下所示:

INSERT INTO SLICED

SELECT      CGNS.CHANNEL,              

            CGNS.PRODUCT_LINE,
            CGNS.ACCOUNT,
            CP.PRODUCT_CATEGORY,
            CP.PRODUCT_SUBCATEGORY,  
            CP.ITEM_SIZE,
            CP.PRIME_PLAN,
            CGNS.PNL_DATE,
            CURRENT_TIMESTAMP, 

            CASE 
                WHEN CGNS.ACCOUNT = 'QUANTITY_SHIPPED' THEN NULL
                ELSE ((CP.AMOUNT / CP_COMPONENTS_TOTAL_AMOUNTS.TOTAL_AMT_FOR_CP_COMPONENT) * CGNS.AMOUNT)
                             END,

            CASE 
                WHEN CGNS.ACCOUNT = 'QUANTITY_SHIPPED' THEN ((CP.AMOUNT / CP_COMPONENTS_TOTAL_AMOUNTS.TOTAL_AMT_FOR_CP_COMPONENT) * CGNS.AMOUNT) 
                ELSE NULL
                    END,

            CGNS.CURRENCY_CODE,
            'Method',

            CASE -- DRIVER AMOUNT
                WHEN CGNS.ACCOUNT = 'QUANTITY_SHIPPED' THEN NULL
                ELSE CP.AMOUNT
            END,


            CASE  -- DRIVER QTY TO DO
                WHEN CGNS.ACCOUNT = 'QUANTITY_SHIPPED' THEN CP.AMOUNT
                ELSE NULL
            END,

            CP.CURRENCY_CODE

FROM CGNS

JOIN ChannelMapper
            ON CGNS.CHANNEL = ChannelMapper.CGNS_CHANNEL

JOIN  AccountMapper
            ON AccountMapper.CGNS_ACCOUNT = CGNS.ACCOUNT


JOIN  PLMapper
            ON PLMapper.CGNS_PRODUCT_LINE = CGNS.PRODUCT_LINE

JOIN  CP
            ON (
                            ChannelMapper.CP_MARKETPLACE_ID = CP.MARKETPLACE_ID
                            AND ChannelMapper.CP_CHANNEL = CP.CHANNEL
                            AND AccountMapper.CP_COMPONENT = CP.CP_COMPONENT
                            AND PLMapper.CP_GL_PRODUCT_GROUP = CP.GL_PRODUCT_GROUP

               )

JOIN   (SELECT CP_COMPONENT, SUM(AMOUNT) AS TOTAL_AMT_FOR_CP_COMPONENT FROM AUTO_PNL_CP GROUP BY CP_COMPONENT) as CP_COMPONENTS_TOTAL_AMOUNTS
            ON CP_COMPONENTS_TOTAL_AMOUNTS.CP_COMPONENT = CP.CP_COMPONENT

这里是解释计划(查询执行计划)的样子:

enter image description here

最佳答案

尝试单独运行查询的各个部分。这样您就可以确定哪些表需要更多时间来查询,并可以为您提供有关如何改进它的想法。也许它会提示您哪里需要索引。

关于mysql - 如何从此查询中消除 "Out of Memory Exception"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17331109/

相关文章:

mysql - Mysql声明错误

mysql - 数据截断 : Incorrect date value:

php - 从 SQL 打印到 PHP?

mysql - 提高 MySQL 查询的性能

mysql - 如何识别 MySQL 数据库中未使用的索引?

java - Java 中的 executeUpdate 方法是线程安全的吗?

mysql - 将 MySQL 表导出为 CSV

sql - 如何在Groovy/Grails Spoc中模拟SQL调用

php - 这个用于创建 MySQL 表的 PHP 脚本有什么问题?

c# - 使用 Group By 优化 LINQ 性能