2016-10-28 138 views
1

在我的查詢我一定要找到所有與逗號分隔的記錄下面的ID。MySQL的IN操作符替代

2,20,44,66,68,85,90,101,102,103,125,168 

所以我寫了下面的查詢任務

SELECT item_id, 
     item_name 
FROM `items` 
WHERE `item_id` IN (2, 20, 44, 66, 
         68, 85, 90, 101, 
         102, 103, 125, 168) 

但問題是,當用逗號分隔的ID列表是大的查詢執行時間將變大。有沒有其他的方式來完成我的任務。

我的表結構之後DESCRIBE表查詢如下。請檢查

Field Type Null Key Default Extra 
asheet_id int(11) unsigned NO PRI NULL auto_increment 
asheet_staff_id int(11) unsigned NO  NULL  
asheet_exam_number int(11) NO  NULL  
+3

正確的索引將(最可能)解決問題 – baao

+0

item_id是主鍵? - 如果不是這樣的話:ALTER TABLE'items' ADD INDEX item_id_index('item_id') – num8er

+0

我不是有更好的方法。在item_id上創建索引以提高性能 – Laazo

回答

0

item_id是主鍵嗎?

執行:

DESCRIBE items; 

,並把結果質疑

1)如果YES所以究您服務器的內存,查詢緩存,查詢併發,網絡/套接字連接和等因素。也許緩慢的部分是不是與您的查詢,但在你的應用程序的另一部分?所以請在問題/評論中描述你如何檢查它。 看看my.cnf有很多PARAMS,可以幫助你調整了MySQL的性能。

2)如果NO所以加索引:ALTER TABLE items ADD INDEX item_id_index (item_id)

IF:它是更好地改變發動機MyISAMitems表沒有得到經常UPDATE查詢,它的速度快於SELECT查詢

另外我想說讓我們嘗試以下技術:

1)UNION SELECT與每個ID,因爲如果它是PK也將作爲SELECT ... LIMIT 1

SELECT item_id, item_name FROM items WHERE item_id = 2 
UNION ALL 
SELECT item_id, item_name FROM items WHERE item_id = 20 
UNION ALL 
. 
. 
UNION ALL 
SELECT item_id, item_name FROM items WHERE item_id = 168 

2)創建一個視圖,並寫信給它:

CREATE OR REPLACE VIEW vw_items AS 
SELECT item_id, item_name FROM items; 

SELECT * FROM vw_items WHERE item_id IN (...); 

也是你的數據庫的情況下,有很多要求,如果items表確有更新查詢嘗試緩存查詢使用memcache爲db,redis

PS做JOINsub query操作,因爲在這兩種情況下,它會使用相同的指數item_id字段將不會提高性能。

+0

首先,你必須分析你的數據與數組相關的是怎樣的(2,20 ,44,66,68,85,90,101,102,103,125,168)。如果你可以在數據庫中存儲數組的值,並且可以使用某些項目表來邏輯一些;你可以使用連接操作。 –

+0

@bikramkc不要讓我發笑。FIRST:如果它是PK它將以最大效率工作並找到需要的東西。第二:做JOIN操作不會獲得性能,因爲即使在JOIN中它也會使用在'item_id'字段中定義的相同索引。 – num8er

0

另一種方法是創建一個Temporary Table,填寫該表與這些數據,然後執行JOIN

create temporary table test(Id int); 

insert into test 
select 2 
union 
select 99 from dual; 

然後執行與該表的連接

SELECT i.item_id, i.item_name 
FROM `items` i 
JOIN test t ON i.item_id = t.Id; 

這種方法是好於擁有巨大的IN列表,因爲列表中的內容將在內部變得扁平化以鏈接OR條件,此外,每個RDBMS都對中的元素數量有限制(不確定約MySQL,但說NETEZZA有5000元左右的限制)。

而不是執行JOIN會生成一個非常有效的執行計劃。如果SQL Server那麼你也可以選擇使用Table Type Variable

+0

是否必須將我的表中的所有記錄包含到臨時表中。如果是這樣,則內部聯接也將返回項目表中的所有記錄。 – Alchemist