在Mysql Query中有内存和超时,它们有连接和Union All语句

时间:2012-09-20 12:13:24

标签: mysql mysql-error-1064

我有两个表项和items_sellers,每个项目都可以在多个卖家中使用。

这里我从另一种方式获得ItemId,sellerId的映射,现在我需要所有这些项目的详细信息。我得到至少5000个key(sellerId)值(itemId)对,通过使用这个地图,我需要从这两个表中获取详细信息。

要获得结果我在下面使用查询:

SELECT 
    table1.column1, 
    table1.column2, 
    table1.column3, 
    table2.column1, 
    table2.column2 
FROM 
    item as table1 
        INNER JOIN ( 
            select 
                key1 as ITEMID, 
                value1 as SELLERID 
            UNION ALL 
            select 
                key2, 
                value2  
            UNION ALL 
            select 
                key3 , 
                value3  
            UNION ALL 
            select 
                key4 , 
                value4 
            UNION ALL
            // ....5000 key value
            pairs
            ) as KEY_VALUE 
            ON table1.item_id = KEY_VALUE.ITEMID 
        INNER JOIN 
            item_sellers as table2 
            ON table1.item_id = table2.item_id 
            AND table2.seller_id = KEY_VALUE.SELLERID
WHERE table1.active = 1

此查询对于3000 - 4000 UNION ALL语句运行完全正常,但是给出错误,即5000+键值对的内存异常/查询超时异常,即5000+ UNION ALL语句。

此查询中是否有任何问题?如果是这样,请通过一些指示灯吗?

有没有办法优化此查询?

PS:当我在此查询中放入所有5000个键值对时,查询字符变为209950个字符?查询是否有任何字符限制?

2 个答案:

答案 0 :(得分:0)

看起来您的子查询缺少from子句。

select 
    key1 as ITEMID, 
    value1 as SELLERID 
UNION ALL 
select 
    key2, 
    value2  
UNION ALL 
// and so on...

它是如何工作的?看起来数据库(令人惊讶地)已经过了这个,然后简单地对数据集做了一个笛卡尔 - 这导致内存飙升到无法应对的程度。

你应该尝试:

select 
    key1 as ITEMID, 
    value1 as SELLERID 
from
    yourTableName
UNION ALL 
select 
    key2, 
    value2
from
    yourTableName
Union all // etc etc

话虽如此,为什么不加入包含where子句的子查询来获取所需的行 - 或者在它们之间使用查找表?

答案 1 :(得分:0)

创建一个临时表并插入其中。

create temporary table mytable (itemid integer, sellerid integer);
insert into mytable (itemid, sellerid) values
(1,2),(2,10)
;
SELECT 
    table1.column1, 
    table1.column2, 
    table1.column3, 
    table2.column1, 
    table2.column2 
FROM 
    item as table1 
        INNER JOIN mytable as KEY_VALUE 
            ON table1.item_id = KEY_VALUE.ITEMID 
        INNER JOIN 
            item_sellers as table2 
            ON table1.item_id = table2.item_id 
            AND table2.seller_id = KEY_VALUE.SELLERID
WHERE table1.active = 1
;
drop table mytable;

sql string lenght会小得多。把它放在最后。