Các cột không liên quan có ảnh hưởng đến thời gian truy vấn của các câu lệnh chọn không?


10

Tôi chỉ tò mò thôi.

Giả sử bạn có bảng 1 triệu bản ghi / hàng.

select order_value from store.orders

Liệu nó có tạo ra sự khác biệt cho dù bảng đó có 1 trường, 2 trường hoặc 100 trường, trong thời gian truy vấn thực tế không? Ý tôi là tất cả các lĩnh vực khác ngoài "order_value."

Ngay bây giờ tôi đang đẩy dữ liệu đến một kho dữ liệu. Đôi khi tôi bỏ các trường vào bảng "có thể được sử dụng trong tương lai, một ngày nào đó" - nhưng chúng không bị truy vấn ngay bây giờ, bởi bất cứ điều gì. Các trường 'không liên quan' này có ảnh hưởng đến các câu lệnh chọn không bao gồm chúng, trực tiếp hay gián tiếp (ý tôi là không)?


Có rất nhiều thông tin về điều này có sẵn trên web. Điều quan trọng là nhận được thông tin gần đây nhất khi công nghệ thay đổi. Những gì bạn đang hỏi phụ thuộc vào thiết lập cụ thể của bạn đến mức không thể đưa ra một câu trả lời rất tốt. Một điểm quan trọng cần nhớ là khi chúng ta chuyển sang SSD, nhiều thứ từng rất quan trọng đối với hiệu suất không còn là vấn đề nữa.
Joe

Câu trả lời:


10

Điều này thực sự phụ thuộc vào chỉ mục và loại dữ liệu.

Sử dụng cơ sở dữ liệu Stack Overflow làm ví dụ, đây là bảng của người dùng:

QUẢ HẠCH

Nó có PK / CX trên cột Id. Vì vậy, đó là toàn bộ dữ liệu bảng được sắp xếp theo Id.

Với chỉ số đó là chỉ mục duy nhất, SQL phải đọc toàn bộ nội dung đó (sans các cột LOB) vào bộ nhớ nếu nó chưa có ở đó.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SET STATISTICS TIME, IO ON 

SELECT u.Id
INTO  #crap1
FROM dbo.Users AS u

Thời gian thống kê và hồ sơ io trông như thế này:

Table 'Users'. Scan count 7, logical reads 80846, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2406 ms,  elapsed time = 446 ms.

Nếu tôi thêm một chỉ mục không bao gồm bổ sung vào chỉ Id

CREATE INDEX ix_whatever ON dbo.Users (Id)

Bây giờ tôi có một chỉ mục nhỏ hơn nhiều đáp ứng truy vấn của tôi.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SELECT u.Id
INTO  #crap2
FROM dbo.Users AS u

Hồ sơ tại đây:

Table 'Users'. Scan count 7, logical reads 6587, physical reads 0, read-ahead reads 6549, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2344 ms,  elapsed time = 384 ms.

Chúng tôi có thể đọc ít hơn rất nhiều và tiết kiệm một ít thời gian CPU.

Không có thêm thông tin về định nghĩa bảng của bạn, tôi thực sự không thể cố gắng tái tạo những gì bạn đang cố gắng để đo lường tốt hơn.

Nhưng bạn đang nói rằng trừ khi có một chỉ mục cụ thể trên cột đơn độc đó, các cột / trường khác cũng sẽ được quét? Đây có phải chỉ là một nhược điểm cố hữu đối với thiết kế của các bảng hàng? Tại sao các lĩnh vực không liên quan sẽ được quét?

Vâng, điều này là cụ thể cho các bảng hàng. Dữ liệu được lưu trữ theo hàng trên các trang dữ liệu. Ngay cả khi dữ liệu khác trên trang không liên quan đến truy vấn của bạn, toàn bộ hàng> trang> chỉ mục đó cần được đọc vào bộ nhớ. Tôi sẽ không nói rằng các cột khác được "quét" nhiều như các trang chúng tồn tại được quét để truy xuất giá trị duy nhất trên chúng có liên quan đến truy vấn.

Sử dụng ví dụ về danh bạ của ol: ngay cả khi bạn chỉ đọc số điện thoại, khi bạn lật trang, bạn đang chuyển họ, tên, địa chỉ, v.v. cùng với số điện thoại.


@ jpmc26 Nó có thể trở nên tồi tệ hơn thế, bởi vì nếu các cột được yêu cầu là một phần của một chỉ mục, truy vấn có thể được phục vụ chỉ bằng cách xem chỉ mục. Nếu các cột không được lập chỉ mục, chúng có thể khiến bản ghi chính được tải và thậm chí các bản ghi thứ cấp cho các loại bảng / cột không bị mờ.
Christopher Schultz

12

Nó phụ thuộc vào cấu trúc bảng và các chỉ mục có sẵn.

  • Trường hợp A: Bảng chung (rowstore), không có chỉ mục trên (order_value).

    Kế hoạch thực hiện duy nhất có thể là đọc toàn bộ bảng (tất nhiên là khác nhau rất nhiều khi đó là 2 so với 200 cột, do đó, một vài so với vài nghìn byte rộng).

  • Trường hợp B: Bảng chung, có một chỉ mục trên (order_value)hoặc một số chỉ mục khác bao gồm cột đó.

    Bây giờ có một kế hoạch tốt hơn, quét toàn bộ chỉ mục (một trong số chúng) - tất nhiên là hẹp hơn nhiều so với toàn bộ bảng, chỉ một vài byte. Điều này làm cho không liên quan nếu bảng có 2 hoặc 200 cột. Chỉ có chỉ số được quét.

  • Trường hợp C: Đó là một bảng cột.

    Như tên của nó, cấu trúc của các bảng này được định hướng theo cột, không theo hàng. Không cần bất kỳ chỉ mục nào, bản thân thiết kế bảng phù hợp để đọc toàn bộ các cột.


Kiến thức của tôi là một chút màu xanh lá cây về vấn đề này. Đó là thông thường nhất (nói cơ sở dữ liệu SQL Server điển hình) để có các bảng hàng, đúng không? Tại sao toàn bộ bảng sẽ được quét nếu chỉ cần trả về một cột / trường? Đây có phải chỉ là vốn có của thiết kế bảng rowstore?
dùng45867

@ user45867 có, dữ liệu được lưu trữ trong các hàng (ngoại trừ một số cột rất lớn được lưu trữ bên ngoài). Khi SQL Server đọc từ đĩa, nó đọc toàn bộ các khối, nó không thể chỉ đọc phần có một cột.
ypercubeᵀᴹ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.