0

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

在这里,我从另一种方式获取 ItemId、sellerId 的映射,现在我需要所有这些项目的详细信息。我得到至少 5000 个键(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 个字符?查询有字数限制吗?

4

2 回答 2

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 字符串长度会小得多。把它放在最后。

于 2012-09-20T12:53:08.440 回答
0

It looks like your subquery is missing the from clause.

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

How is it even working at all? It looks like the database is (surprisingly) getting past this and then simply doing a cartesian on the set of data - which is causing memory to spike to the point where it can't cope.

You should try:

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

Having said that, why don't you join to the subquery that contains a where clause to get the rows you need - or use a lookup table between them?

于 2012-09-20T12:18:10.407 回答