2009-01-17 24 views

Trả lời

7

Có lẽ bạn sẽ tốt hơn với một cách khác để thực hiện truy vấn của mình?

Tôi đề nghị bạn tải các giá trị khớp của bạn vào một bảng một cột và sau đó nối bên trong cột được truy vấn vào cột đơn trong bảng mới.

Thay vì

SELECT a, b, c FROM t1 WHERE d in (d1, d2, d3, d4, ...) 

xây dựng một bảng temp với 1 cột, gọi nó là "dval"

 
dval 
---- 
d1 
d2 
d3 
SELECT a, b, c FROM t1 
INNER JOIN temptbl ON t1.d = temptbl.dval 
+0

Cảm ơn bạn Chúng tôi cũng đang lên kế hoạch giải pháp tương tự cho vấn đề này. Tuy nhiên, việc thêm một bảng mới trong các cài đặt hiện có sẽ cần một số xác nhận và thời gian bổ sung. giải pháp tạm thời mà chúng tôi nghĩ là chia tách truy vấn. –

+0

Tôi không nhớ mber cho chắc chắn, nhưng tôi sẽ nghĩ rằng một bảng tạm thời sẽ không đòi hỏi nhiều trong cách của các điều khoản, vì nó xảy ra thoáng qua trong tempdb.Nhưng trong ngắn hạn, tôi hy vọng rằng vòng lặp trên những gì bạn đã xác định là một số arg chấp nhận được sẽ làm việc. – dkretz

+0

Hoặc nếu bạn cần tất cả chúng cùng một lúc, bạn có thể thực hiện một UNION trên nhiều câu lệnh. – dkretz

4

Phải hỏi về giới hạn khi một trong hai làm một truy vấn SQL hoặc thiết kế cơ sở dữ liệu là một chỉ báo tốt cho thấy bạn đang làm sai.

+0

@PhoenixRedeemer vâng, tôi đồng ý cách tiếp cận của tôi là sai. Thay đổi toàn bộ thiết kế sẽ mất một thời gian, vì vậy tôi nghĩ rằng một số giải pháp tạm thời có thể giải quyết vấn đề –

0

Tôi đã sử dụng IN với danh sách ID khá lớn - Tôi nghi ngờ rằng vấn đề bộ nhớ không nằm trong chính truy vấn đó. Làm thế nào bạn lấy kết quả?

Truy vấn này, ví dụ như là từ một trang web trực tiếp:

SELECT DISTINCT c.id, c.name FROM categories c 
LEFT JOIN product_categories pc ON c.id = pc.category_id 
LEFT JOIN products p ON p.id = pc.product_id 
WHERE p.location_id IN (
955,891,901,877,736,918,900,836,846,914,771,773,833, 
893,782,742,860,849,850,812,945,775,784,746,1036,863, 
750,763,871,817,749,838,986,794,867,758,923,804,733, 
949,808,837,741,747,954,939,865,857,787,820,783,760, 
911,745,928,818,887,847,978,852 
) ORDER BY c.name ASC 

vượt qua đầu tiên của tôi vào mã là terribly ngây thơ và có khoảng 10 của các truy vấn này đang ở trên một trang duy nhất và cơ sở dữ liệu không chớp mắt .

Bạn có thể, tất nhiên, đang chạy một danh sách các giá trị 100k mà sẽ là một câu chuyện hoàn toàn khác nhau.

+1

@tobyhede: Ngay cả trong trường hợp của chúng tôi, truy vấn hoạt động tốt cho một tập dữ liệu nhỏ. Tôi đã gặp vấn đề về bộ nhớ này khi số lượng vượt quá 4K. –

0

Tôi không biết giới hạn là gì, nhưng tôi cũng đã gặp vấn đề này trước đó. Tôi phải viết lại câu hỏi của mình như sau:

select * from foo 
    where id in (select distinct foo_id from bar where ...) 
2

Tôi chỉ sử dụng IN và NOT IN khi điều kiện rất nhỏ (dưới 100 hàng hoặc hơn). Nó hoạt động tốt trong các tình huống đó. Tôi sử dụng một OUTER JOIN khi điều kiện là lớn như truy vấn không phải tìm kiếm "IN" điều kiện cho mỗi tuple. Bạn chỉ cần kiểm tra bảng mà bạn muốn tất cả các hàng đến từ đó.

Đối với "IN" điều kiện tham gia IS NOT NULL

Đối với "NOT IN" điều kiện tham gia IS NULL

ví dụ

/* Get purchase orders that have never been rejected */ 
SELECT po.* 
FROM PurchaseOrder po LEFT OUTER JOIN 
    (/* Get po's that have been rejected */ 
    SELECT po.PurchaesOrderID 
    FROM PurchaseOrder po INNER JOIN 
     PurchaseOrderStatus pos ON po.PurchaseOrderID = pos.PurchaseOrderID 
    WHERE pos.Status = 'REJECTED' 
    ) por ON po.PurchaseOrderID = por.PurchaseOrderID 
WHERE por.PurchaseOrderID IS NULL /* We want NOT IN */ 
0

I "m gặp một vấn đề tương tự nhưng chỉ đi qua 100 3 ids chữ số trong điều khoản trong tôi. Khi tôi nhìn vào vết đống, nó thực sự cắt đứt các giá trị riêng biệt dấu phẩy trong mệnh đề IN. Tôi don' Nếu có liên quan, tôi đang sử dụng khung công tác symfony ... Tôi đang kiểm tra xem nó có phải là một propel hay không. vấn đề nhưng chỉ muốn xem nếu nó có thể là sql

Các vấn đề liên quan