2010-02-14 32 views
19

Xin chào Tôi đã thực hiện kiểm tra SQL và không rõ ràng/tò mò về một câu hỏi:Trong đó chuỗi là các truy vấn và truy vấn phụ được thực thi bởi công cụ SQL?

Trong đó chuỗi truy vấn và truy vấn phụ được thực thi bởi công cụ SQL?

câu trả lời là

  1. truy vấn chính -> truy vấn phụ -> truy vấn phụ phụ và vân vân
  2. phụ truy vấn phụ -> phụ truy vấn -> truy vấn Thủ
  3. toàn bộ truy vấn được xem tại một thời điểm
  4. Không có trình tự phiên dịch cố định, trình phân tích cú pháp truy vấn quyết định bay

Tôi đã chọn câu trả lời cuối cùng (chỉ giả sử rằng nó là đáng tin cậy nhất w.r.t. khác). Bây giờ, sự tò mò:

nơi tôi có thể đọc về cơ chế này và một thời gian ngắn là gì?

Cảm ơn bạn.

Trả lời

12

Tùy chọn 4 đóng.

SQL là declarative: bạn nói với trình tối ưu hóa truy vấn những gì bạn muốn và nó hoạt động tốt nhất (tùy thuộc vào thời gian/"chi phí" vv) cách thực hiện.Điều này có thể thay đổi đối với các truy vấn và bảng bên ngoài giống nhau tùy thuộc vào thống kê, phân phối dữ liệu, số lượng hàng, song song và thần biết điều gì khác.

Điều này có nghĩa là không có thứ tự cố định. Nhưng nó không hoàn toàn "on the fly"

Ngay cả với các máy chủ giống hệt nhau, lược đồ, truy vấn, và dữ liệu tôi đã nhìn thấy kế hoạch thực hiện khác nhau

0

Nó thường phụ thuộc vào DBMS của bạn, nhưng ... Tôi nghĩ câu trả lời thứ hai là hợp lý hơn. Truy vấn chính thường không thể được tính nếu không có kết quả truy vấn phụ.

+0

và trong các truy vấn phụ khác thường phụ thuộc vào truy vấn gốc (truy vấn con tương quan). ps: hello từ phpclub ;-) – zerkms

0

Công cụ SQL cố gắng tối ưu hóa thứ tự các truy vấn (phụ) được thực thi. Phần quyết định về điều đó được gọi là trình tối ưu hóa truy vấn. Trình tối ưu hóa truy vấn biết có bao nhiêu hàng trong mỗi bảng, bảng nào có chỉ mục và trên các trường nào. Nó sử dụng thông tin đó để quyết định phần nào cần thực hiện trước.

20

Tôi nghĩ câu trả lời 4 là chính xác. Có một số cân nhắc:

loại truy vấn con - có phải là nó có liên quan hay không. Hãy xem xét:

SELECT * 
FROM t1 
WHERE id IN (
      SELECT id 
      FROM t2 
      ) 

Ở đây, truy vấn phụ không tương quan với truy vấn bên ngoài. Nếu số lượng giá trị trong t2.id nhỏ so với t1.id, có thể hiệu quả nhất để thực hiện truy vấn con đầu tiên và giữ kết quả trong bộ nhớ, sau đó quét t1 hoặc chỉ mục trên t1.id, khớp với các giá trị được lưu trong bộ nhớ cache.

Nhưng nếu truy vấn là:

SELECT * 
FROM t1 
WHERE id IN (
      SELECT id 
      FROM t2 
      WHERE t2.type = t1.type 
      ) 

đây subquery tương quan - không có cách nào để tính toán subquery trừ t1.type được biết đến. Vì giá trị cho t1.type có thể khác nhau cho mỗi hàng của truy vấn bên ngoài, truy vấn con này có thể được thực hiện một lần cho mỗi hàng của truy vấn bên ngoài.

Sau đó, một lần nữa, RDBMS có thể thực sự thông minh và nhận ra rằng chỉ có một vài giá trị có thể cho t2.type. Trong trường hợp đó, nó vẫn có thể sử dụng phương pháp được sử dụng cho truy vấn con không tương quan nếu có thể đoán rằng chi phí thực hiện truy vấn con một lần sẽ rẻ hơn khi thực hiện nó cho mỗi hàng.

+0

Thak bạn cho phản ứng, bất kỳ ý tưởng về nơi để đọc về, nguồn tốt nhất? – Igor

+2

Nếu trong ví dụ thứ hai thay vì 'từ t2' chúng ta có' từ t2, t1' thì truy vấn chính và truy vấn phụ không tương quan. Tôi có đúng không? – alex

+0

Đó là chính xác. Biểu thức t1.type trong câu lệnh con của WHERE sau đó sẽ được giải quyết tới t1 trong mệnh đề FROM của truy vấn phụ, không phải của truy vấn bên ngoài. Truy vấn con sau đó sẽ không có bất kỳ tham chiếu nào nữa cho truy vấn bên ngoài và do đó sẽ không được tương quan. –

1

Nếu bạn muốn một cái gì đó để đọc lên trên các chủ đề này, có được một bản sao của Bên trong SQL Server 2008: Truy vấn T-SQL. Nó có hai chương dành riêng về cách truy vấn được xử lý hợp lý và thể chất trong SQL Server.

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