chọn * vs chọn cột


124

Nếu tôi chỉ cần 2/3 cột và tôi truy vấn SELECT *thay vì cung cấp các cột đó trong truy vấn chọn, liệu có sự suy giảm hiệu suất nào liên quan đến nhiều / ít I / O hoặc bộ nhớ không?

Chi phí mạng có thể xuất hiện nếu tôi chọn * mà không cần.

Nhưng trong một hoạt động được chọn, công cụ cơ sở dữ liệu luôn lấy bộ dữ liệu nguyên tử từ đĩa, hay nó chỉ kéo các cột được yêu cầu trong hoạt động chọn?

Nếu nó luôn kéo một tuple thì I / O trên đầu là như nhau.

Đồng thời, có thể có mức tiêu thụ bộ nhớ để loại bỏ các cột được yêu cầu từ bộ dữ liệu, nếu nó kéo một bộ dữ liệu.

Vì vậy, nếu đó là trường hợp, chọn một sốColumn sẽ có nhiều bộ nhớ hơn so với chọn *


Có một RDBMS cụ thể mà bạn đang hỏi về không? Có thể là cách SELECTcác truy vấn được thực thi / xử lý khác với cơ sở dữ liệu.
Lèse majesté

10
Ngoài ra, trong PostgreSQL, nếu bạn nói CREATE VIEW foo_view AS SELECT * FROM foo;, sau đó thêm các cột vào bảng foo sau đó, các cột đó sẽ không tự động hiển thị trong foo_view như mong đợi. Nói cách khác, *trong bối cảnh này chỉ mở rộng một lần (tại thời điểm tạo chế độ xem), không phải cho mỗi CHỌN. Do các biến chứng phát sinh từ ALTER TABLE, tôi sẽ nói rằng (trong thực tế) *được coi là có hại.
Joey Adams

@JoeyAdams - không chỉ PostgresQL, đây cũng là hành vi của Oracle.
APC

1
@OMG Ponies: Tôi không biết bài tương tự. Tuy nhiên những arenot thực sự similer. @ Lèse majesté: Tôi đang nói về RDBMS chung. không phải về bất kỳ nhà cung cấp cụ thể nào @Joey Adams: Hmm Tôi biết rằng * không an toàn. chỉ muốn thảo luận về các vấn đề hiệu suất liên quan.
Neel Basu

Câu trả lời:


31

Nó luôn kéo một tuple (trừ trường hợp bảng được phân chia theo chiều dọc - được chia thành các phần cột), vì vậy, để trả lời câu hỏi bạn đã hỏi, không quan trọng từ góc độ hiệu suất. Tuy nhiên, vì nhiều lý do khác, (bên dưới), bạn phải luôn chọn cụ thể những cột bạn muốn, theo tên.

Nó luôn kéo theo một tuple, bởi vì (trong mọi nhà cung cấp RDBMS mà tôi quen thuộc), cấu trúc lưu trữ trên đĩa cho mọi thứ (bao gồm cả dữ liệu bảng) dựa trên các Trang I / O được xác định (ví dụ: trong SQL Server 8 kilobyte). Và mỗi I / O đọc hoặc ghi là bởi Trang .. Tức là, mỗi lần ghi hoặc đọc là một Trang dữ liệu hoàn chỉnh.

Do ràng buộc cấu trúc cơ bản này, một hậu quả là Mỗi hàng dữ liệu trong cơ sở dữ liệu phải luôn ở trên một và chỉ một trang. Nó không thể trải rộng trên nhiều Trang dữ liệu (ngoại trừ những thứ đặc biệt như đốm màu, trong đó dữ liệu blob thực tế được lưu trữ trong các phần Trang riêng biệt và cột hàng của bảng thực tế sau đó chỉ nhận được một con trỏ ...). Nhưng những trường hợp ngoại lệ này chỉ là ngoại lệ và thường không áp dụng trừ trường hợp đặc biệt (đối với loại dữ liệu đặc biệt hoặc tối ưu hóa nhất định cho trường hợp đặc biệt)
Ngay cả trong những trường hợp đặc biệt này, nói chung, chính hàng dữ liệu của bảng (có chứa con trỏ tới dữ liệu thực tế cho Blob, hoặc bất cứ điều gì), nó phải được lưu trữ trên một trang IO duy nhất ...

NGOẠI LỆ. Nơi duy nhất Select *ổn, nằm trong truy vấn phụ sau mệnh đề Existshoặc Not Existsvị ngữ, như trong:

   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

EDIT: Để giải quyết nhận xét @Mike Sherer, Có, đó là sự thật, cả về mặt kỹ thuật, với một chút định nghĩa cho trường hợp đặc biệt của bạn và về mặt thẩm mỹ. Đầu tiên, ngay cả khi tập hợp các cột được yêu cầu là tập hợp con của các cột được lưu trữ trong một số chỉ mục, bộ xử lý truy vấn phải tìm nạp mọi cột được lưu trong chỉ mục đó, không chỉ các cột được yêu cầu, vì cùng một lý do - TẤT CẢ I / O phải được thực hiện trong trang và dữ liệu chỉ mục được lưu trữ trong IO Trang giống như dữ liệu bảng. Vì vậy, nếu bạn định nghĩa "tuple" cho một trang chỉ mục là tập hợp các cột được lưu trữ trong chỉ mục, thì câu lệnh vẫn đúng.
và tuyên bố là đúng về mặt thẩm mỹ bởi vì vấn đề là nó tìm nạp dữ liệu dựa trên những gì được lưu trữ trong trang I / O, chứ không phải trên những gì bạn yêu cầu và điều này đúng cho dù bạn đang truy cập Trang I / O của bảng cơ sở hay chỉ mục Trang I / O.

Đối với các lý do khác không sử dụng Select *, xem Tại sao được SELECT *coi là có hại? :


"Nó luôn luôn kéo một tuple" bạn có chắc không? Hmm Được rồi, tôi đã đúng. nếu đó là trường hợp select *sẽ có ít chi phí bộ nhớ hơn select columnnhưng chi phí I / O tương tự. Vì vậy, nếu chúng ta rời khỏi mạng. select *nếu ít chi phí hơn so vớiselect column
Neel Basu

10
Đây không phải là sự thật. Một ví dụ ngoài đỉnh đầu của tôi là khi bạn chỉ muốn giá trị của một cột được lập chỉ mục trong MySQL (ví dụ: chỉ để kiểm tra sự tồn tại của hàng) và bạn đang sử dụng công cụ lưu trữ MyISAM, nó sẽ lấy dữ liệu từ Tệp MYI, có thể nằm trong bộ nhớ và thậm chí không vào đĩa!
Mike Sherov

Ya nếu bộ tuple được yêu cầu nằm trong bộ nhớ sẽ không có I / O nhưng đó là trường hợp đặc biệt. Vậy mùa hè là gì. Nếu tôi chọn một số Cột được lập chỉ mục thì toàn bộ tuple không được đọc? Nếu không thì toàn bộ tuple được đọc?
Neel Basu

Tôi không chắc chắn chính xác làm thế nào MySql thực hiện bộ nhớ đệm, nhưng trong SQL Server và trong Oracle, ngay cả khi dữ liệu nằm trong bộ nhớ cache trong bộ nhớ, nó vẫn truy cập nó bằng cách sử dụng cùng cấu trúc Trang như khi truy cập từ đĩa. có nghĩa là nó sẽ yêu cầu một I / O bộ nhớ trên mỗi trang dữ liệu ... chính xác giống như trên đĩa. (tất nhiên ngoại trừ bộ nhớ I / O nhanh hơn nhiều so với đĩa I / O). Thật vậy, đó là một mục tiêu của thiết kế bộ nhớ đệm, để làm cho quá trình truy cập hoàn toàn độc lập về vị trí của dữ liệu.
Charles Bretana

2
Bạn có thể đánh vần thêm "vì nhiều lý do khác" không? Bởi vì những điều đó không rõ ràng với tôi. Nếu hiệu suất không thành vấn đề, tại sao phải quan tâm đến việc yêu cầu tên cột?
Dennis

111

Có một số lý do bạn không bao giờ (không bao giờ) sử dụng SELECT *trong mã sản xuất:

  • vì bạn không cung cấp cho cơ sở dữ liệu của mình bất kỳ gợi ý nào về những gì bạn muốn, trước tiên, nó sẽ cần kiểm tra định nghĩa của bảng để xác định các cột trên bảng đó. Việc tra cứu đó sẽ tốn một chút thời gian - không nhiều trong một truy vấn - nhưng nó sẽ tăng thêm theo thời gian

  • nếu bạn chỉ cần 2/3 số cột, bạn đang chọn quá nhiều dữ liệu cần lấy từ đĩa và gửi qua mạng

  • nếu bạn bắt đầu dựa vào các khía cạnh nhất định của dữ liệu, ví dụ thứ tự các cột được trả về, bạn có thể gặp bất ngờ khó chịu khi bảng được sắp xếp lại và các cột mới được thêm vào (hoặc các cột hiện có bị xóa)

  • trong SQL Server (không chắc chắn về các cơ sở dữ liệu khác), nếu bạn cần một tập hợp con của các cột, luôn có khả năng một chỉ mục không được nhóm có thể đáp ứng yêu cầu đó (chứa tất cả các cột cần thiết). Với một SELECT *, bạn đang từ bỏ khả năng đó ngay từ khi đi. Trong trường hợp cụ thể này, dữ liệu sẽ được truy xuất từ ​​các trang chỉ mục (nếu các trang chứa tất cả các cột cần thiết) và do đó, I / O của đĩa chi phí bộ nhớ sẽ ít hơn nhiều so với thực hiện SELECT *....truy vấn.

Đúng, ban đầu phải gõ thêm một chút (các công cụ như SQL Prompt cho SQL Server thậm chí sẽ giúp bạn ở đó) - nhưng đây thực sự là một trường hợp có một quy tắc không có ngoại lệ: đừng bao giờ sử dụng CHỌN * trong mã sản xuất của bạn. KHÔNG BAO GIỜ.


13
Trong khi đồng ý với bạn trong thực tế, bạn chắc chắn đúng trong mọi trường hợp khi tìm nạp dữ liệu cột từ bảng, vì câu hỏi này giải quyết), tuy nhiên, nhấn mạnh vào EVER khiến tôi chỉ ra rằng quy tắc này không chung cho TẤT CẢ các truy vấn Sql .. . cụ thể, nó được sử dụng trong một truy vấn con sau một vị từ EXISTS, (như trong Where Exists (Select * From ...) việc sử dụng Select *chắc chắn không có vấn đề gì, và trong một số vòng tròn được coi là một cách thực hành tốt nhất.
Charles Bretana

3
@Charles Bretana: vâng, đây IF EXISTS(SELECT *...là trường hợp đặc biệt - vì ở đó, không có dữ liệu nào thực sự được lấy, nhưng đó chỉ là kiểm tra sự tồn tại, CHỌN * không phải là vấn đề ở đó ...
marc_s

1
Điều gì sẽ xảy ra nếu tôi đang phát triển một API cho phép lấy dữ liệu từ một trong các bảng của tôi. Vì tôi không biết người dùng nào quan tâm đến dữ liệu nào, tôi cho rằng CHỌN * sẽ được chấp nhận?
Simon Bengtsson

1
@SimonBengtsson: Tôi vẫn sẽ tranh luận về vấn đề này - giả sử bạn có một số dữ liệu "hành chính" trong các cột cụ thể trong bảng mà bạn không muốn tiếp xúc với khách hàng? Tôi sẽ luôn chỉ định rõ ràng một danh sách các cột cần tìm nạp
marc_s

1
Đúng. Còn khi truy vấn một chế độ xem được thiết lập cụ thể để sử dụng với API thì sao?
Simon Bengtsson

21

Bạn nên luôn luôn chỉ selectcác cột mà bạn thực sự cần. Không bao giờ kém hiệu quả hơn khi chọn ít hơn thay vì nhiều hơn và bạn cũng gặp ít tác dụng phụ không mong muốn hơn - như truy cập các cột kết quả của bạn ở phía máy khách theo chỉ mục, sau đó các chỉ mục đó trở nên không chính xác bằng cách thêm một cột mới vào bảng.

[sửa]: Truy cập Mete. Não ngu vẫn thức dậy.


3
+1 cho trường hợp cạnh mà tôi tin rằng không nhiều người sẽ nghĩ đến ngay từ cái nhìn đầu tiên - các chỉ mục ở phía máy khách và các cột được thêm / thay đổi.
Tomas Aschan

1
Phải, nhưng việc sử dụng các chỉ số số cho các cột phổ biến? Tôi đã luôn truy cập dữ liệu cột bằng khóa chuỗi hoặc tên thuộc tính nếu sử dụng ORM.
Lèse majesté

11
đã thấy điều này từ lâu, lập trình viên cơ sở đã chọn * từ một bảng và đưa ra các giả định về thứ tự cột; tất cả mã của anh ta bị phá vỡ ngay khi người khác thay đổi bảng. Những gì chúng tôi đã có niềm vui.
Paul McKenzie

7
Có lẽ là một ý tưởng tồi khi sử dụng thứ tự cột nói chung chỉ vì mục đích dễ đọc mã, đôi khi rất tệ khi sử dụng SELECT * nó.
Lèse majesté

2
Wow, truy cập vào các cột bằng chỉ số trong mã khách hàng có vẻ như một phi thường ý tưởng tồi. Đối với vấn đề đó, dựa vào thứ tự các cột xuất hiện trong tập kết quả theo bất kỳ cách nào tôi cảm thấy rất bẩn đối với tôi.
Matt Peterson

7

Trừ khi bạn đang lưu trữ các đốm màu lớn, hiệu suất không phải là vấn đề đáng lo ngại. Lý do lớn không sử dụng CHỌN * là nếu bạn đang sử dụng các hàng được trả về dưới dạng bộ dữ liệu, các cột sẽ quay trở lại theo bất kỳ thứ tự nào mà lược đồ xảy ra để chỉ định và nếu thay đổi đó, bạn sẽ phải sửa tất cả mã của mình.

Mặt khác, nếu bạn sử dụng quyền truy cập theo kiểu từ điển thì việc các cột quay trở lại theo thứ tự nào là không quan trọng vì bạn luôn truy cập chúng theo tên.


6

Điều này ngay lập tức khiến tôi nghĩ về một bảng tôi đang sử dụng có chứa một loại cột blob; nó thường chứa một hình ảnh JPEG, Mbkích thước vài s.

Không cần phải nói tôi đã không SELECT cột đó trừ khi tôi thực sự cần nó. Có dữ liệu đó trôi nổi xung quanh - đặc biệt là khi tôi chọn các hàng mulitple - chỉ là một rắc rối.

Tuy nhiên, tôi sẽ thừa nhận rằng tôi thường truy vấn tất cả các cột trong một bảng.


20
Các cột LOB luôn là ví dụ yêu thích của tôi về sự nguy hiểm của CHỌN *. Vì vậy, tôi đã định nâng đỡ bạn, cho đến khi tôi đọc đoạn thứ ba. TSK tsk. Điều gì xảy ra nếu một số nhà phát triển khác thêm BLOB vào bảng hiện không có cột như vậy?
APC

1
@APC, tôi ước tôi có thể nâng cao nhận xét của bạn nhiều hơn. Hãy nghĩ về đồng nghiệp nghèo của bạn, người chỉ muốn thêm một cột mà không gây ra một cuộc khủng hoảng hiệu suất lớn! Hãy nghĩ về việc họ sẽ tức giận như thế nào khi họ phát hiện ra sau vài giờ lựa chọn trông ngây thơ của bạn *.
Mike Sherov

1
@ user256007, vâng, ngay cả khi không có BLOB ... BLOB chỉ minh họa ví dụ cực đoan. Kiểm tra phản hồi của tôi với Charles, đôi khi việc chọn các cột cụ thể có thể cho phép bạn lấy dữ liệu từ bộ nhớ mà không cần vào đĩa!
Mike Sherov

1
@Richard, tôi nghĩ rằng chúng rất tuyệt khi tối ưu hóa hiệu suất DB không phải là mối quan tâm chính của bạn, đó là 99% thời gian. Như với hầu hết các khung công tác, họ có xu hướng khái quát hóa mọi thứ để cho phép phát triển nhanh hơn trong khi hy sinh hiệu suất thuần túy. Như Knuth đã nói: "Tối ưu hóa sớm là gốc rễ của mọi tội lỗi." Khi bạn đến điểm mà bạn cần lo lắng về hiệu suất của các cột được chọn so với chọn *, (hỏi Twitter về RoR), bạn có thể lo lắng về điều đó và tối ưu hóa nó sau đó. Nếu khung không đủ mạnh để hỗ trợ điều đó, thì tôi sẽ nói rằng bạn đang sử dụng khung sai.
Mike Sherov

1
@ user256007 - quy tắc chung là "không sử dụng CHỌN * '. Câu trả lời từ marc_s có tất cả các lý do tại sao lại như vậy.
APC

6

Trong quá trình chọn SQL, DB sẽ luôn đề cập đến siêu dữ liệu cho bảng, bất kể đó là CHỌN * cho CHỌN a, b, c ... Tại sao? Vì đó là thông tin về cấu trúc và bố cục của bảng trên hệ thống.

Nó phải đọc thông tin này vì hai lý do. Một, chỉ đơn giản là biên dịch các tuyên bố. Nó cần đảm bảo rằng bạn chỉ định một bảng hiện có ít nhất. Ngoài ra, cấu trúc cơ sở dữ liệu có thể đã thay đổi kể từ lần cuối cùng một câu lệnh được thực thi.

Bây giờ, rõ ràng, siêu dữ liệu DB được lưu trữ trong hệ thống, nhưng nó vẫn đang xử lý cần phải hoàn thành.

Tiếp theo, siêu dữ liệu được sử dụng để tạo kế hoạch truy vấn. Điều này xảy ra mỗi khi một tuyên bố được biên soạn là tốt. Một lần nữa, điều này chạy với siêu dữ liệu được lưu trong bộ nhớ cache, nhưng nó luôn được thực hiện.

Lần duy nhất quá trình xử lý này không được thực hiện là khi DB đang sử dụng truy vấn được biên dịch trước hoặc đã lưu trữ một truy vấn trước đó. Đây là đối số để sử dụng các tham số ràng buộc thay vì SQL bằng chữ. "CHỌN * TABLE TABLE WHERE key = 1" là một truy vấn khác với "CHỌN * TABLE TABLE WHERE key =?" và "1" bị ràng buộc trong cuộc gọi.

DB phụ thuộc rất nhiều vào bộ nhớ đệm trang cho công việc. Nhiều DB hiện đại đủ nhỏ để phù hợp hoàn toàn với bộ nhớ (hoặc, có lẽ tôi nên nói, bộ nhớ hiện đại đủ lớn để phù hợp với nhiều DB). Sau đó, chi phí I / O chính của bạn ở mặt sau là ghi nhật ký và xóa trang.

Tuy nhiên, nếu bạn vẫn đang nhấn đĩa cho DB của mình, việc tối ưu hóa chính được thực hiện bởi nhiều hệ thống là dựa vào dữ liệu trong các chỉ mục, thay vì chính các bảng.

Nếu bạn có:

CREATE TABLE customer (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    city VARCHAR(30),
    state VARCHAR(30),
    zip VARCHAR(10));

CREATE INDEX k1_customer ON customer(id, name);

Sau đó, nếu bạn thực hiện "CHỌN id, đặt tên TỪ khách hàng WHERE id = 1", rất có khả năng DB của bạn sẽ lấy dữ liệu này từ chỉ mục, thay vì từ các bảng.

Tại sao? Dù sao thì nó cũng có thể sử dụng chỉ mục để đáp ứng truy vấn (so với quét bảng) và mặc dù 'name' không được sử dụng trong mệnh đề where, chỉ mục đó vẫn sẽ là lựa chọn tốt nhất cho truy vấn.

Bây giờ cơ sở dữ liệu có tất cả dữ liệu cần thiết để đáp ứng truy vấn, vì vậy không có lý do gì để tự đánh vào các trang của bảng. Việc sử dụng chỉ mục dẫn đến lưu lượng đĩa ít hơn do bạn có mật độ hàng cao hơn trong chỉ mục so với bảng nói chung.

Đây là một giải thích lượn sóng tay về một kỹ thuật tối ưu hóa cụ thể được sử dụng bởi một số cơ sở dữ liệu. Nhiều người có một số kỹ thuật tối ưu hóa và điều chỉnh.

Cuối cùng, SELECT * hữu ích cho các truy vấn động mà bạn phải nhập bằng tay, tôi sẽ không bao giờ sử dụng nó cho "mã thực". Việc xác định các cột riêng lẻ cung cấp cho DB nhiều thông tin hơn mà nó có thể sử dụng để tối ưu hóa truy vấn và cung cấp cho bạn quyền kiểm soát tốt hơn trong mã của mình trước các thay đổi của lược đồ, v.v.


Tôi sẽ đánh giá thấp câu trả lời của bạn, chỉ vì bạn sử dụng KHÔNG NULL cùng với KHÓA CHÍNH. Có một lý do tốt để bạn viết theo cách này?
Học viên

4

Tôi nghĩ rằng không có câu trả lời chính xác cho câu hỏi của bạn, bởi vì bạn có suy nghĩ về hiệu suất và phương tiện duy trì các ứng dụng của bạn. Select columnhiệu quả hơn select *, nhưng nếu bạn đang phát triển một hệ thống đối tượng được định hướng, thì bạn sẽ thích sử dụng object.propertiesvà bạn có thể cần một thuộc tính trong bất kỳ phần nào của ứng dụng, sau đó bạn sẽ cần viết nhiều phương thức hơn để có được các thuộc tính trong các tình huống đặc biệt nếu bạn không sử dụng select *và dân cư tất cả các thuộc tính. Ứng dụng của bạn cần có hiệu suất tốt khi sử dụng select *và trong một số trường hợp, bạn sẽ cần sử dụng cột chọn để cải thiện hiệu suất. Sau đó, bạn sẽ có hai thế giới tốt hơn, cơ sở để viết và duy trì các ứng dụng và hiệu suất khi bạn cần hiệu suất.


4

Câu trả lời được chấp nhận ở đây là sai. Tôi đã bắt gặp điều này khi một câu hỏi khác được đóng lại như một bản sao của câu hỏi này (trong khi tôi vẫn đang viết câu trả lời của mình - grr - do đó SQL bên dưới tham chiếu câu hỏi khác).

Bạn phải luôn luôn sử dụng thuộc tính CHỌN, thuộc tính .... KHÔNG CHỌN *

Nó chủ yếu cho các vấn đề hiệu suất.

CHỌN tên TỪ người dùng WHERE name = 'John';

Không phải là một ví dụ rất hữu ích. Thay vào đó hãy xem xét:

SELECT telephone FROM users WHERE name='John';

Nếu có một chỉ mục trên (tên, điện thoại) thì truy vấn có thể được giải quyết mà không cần phải tra cứu các giá trị liên quan từ bảng - có một chỉ mục bao trùm .

Hơn nữa, giả sử bảng có BLOB chứa ảnh của người dùng và CV đã tải lên và bảng tính ... sử dụng SELECT * sẽ đưa tất cả thông tin này trở lại vào bộ đệm DBMS (loại bỏ thông tin hữu ích khác từ bộ đệm). Sau đó, tất cả sẽ được gửi đến máy khách bằng cách sử dụng hết thời gian trên mạng và bộ nhớ trên máy khách để lấy dữ liệu dư thừa.

Nó cũng có thể gây ra các vấn đề chức năng nếu máy khách truy xuất dữ liệu dưới dạng một mảng được liệt kê (chẳng hạn như mysql_fetch_array của PHP ($ x, MYSQL_NUM)). Có thể khi mã được viết 'phone' là cột thứ ba được trả về bởi SELECT *, nhưng sau đó ai đó đi cùng và quyết định thêm địa chỉ email vào bảng, được đặt trước 'phone'. Trường mong muốn bây giờ được chuyển sang cột thứ 4.


2

Có nhiều lý do để làm mọi thứ. Tôi sử dụng CHỌN * rất nhiều trên PostgreSQL vì có rất nhiều điều bạn có thể làm với CHỌN * trong PostgreQuery mà bạn không thể thực hiện với danh sách cột rõ ràng, đặc biệt là khi trong các thủ tục được lưu trữ. Tương tự như vậy trong Informix, CHỌN * trên cây bảng được kế thừa có thể cung cấp cho bạn các hàng lởm chởm trong khi danh sách cột rõ ràng không thể vì các cột bổ sung trong các bảng con cũng được trả về.

Lý do chính tại sao tôi làm điều này trong PostgreSQL là vì nó đảm bảo rằng tôi có được một loại được định dạng tốt cụ thể cho một bảng. Điều này cho phép tôi lấy kết quả và sử dụng chúng làm kiểu bảng trong PostgreSQL. Điều này cũng cho phép nhiều tùy chọn hơn trong truy vấn so với danh sách cột cứng nhắc.

Mặt khác, danh sách cột cứng nhắc cung cấp cho bạn kiểm tra mức ứng dụng rằng các lược đồ db không thay đổi theo một số cách nhất định và điều này có thể hữu ích. (Tôi thực hiện kiểm tra như vậy ở cấp độ khác.)

Về hiệu suất, tôi có xu hướng sử dụng VIEW và các loại thủ tục được lưu trữ trả về các kiểu (và sau đó là danh sách cột bên trong thủ tục được lưu trữ). Điều này cho phép tôi kiểm soát những loại được trả lại.

Nhưng hãy nhớ rằng tôi đang sử dụng SELECT * thường chống lại một lớp trừu tượng hơn là các bảng cơ sở.


2

Tham khảo lấy từ bài viết này:

Nếu không có CHỌN *: Khi bạn đang sử dụng LỰA CHỌN * * Tại thời điểm đó, bạn đang chọn nhiều cột hơn từ cơ sở dữ liệu và một số cột này có thể không được ứng dụng của bạn sử dụng. Điều này sẽ tạo thêm chi phí và tải trên hệ thống cơ sở dữ liệu và truyền dữ liệu nhiều hơn trên mạng.

Với CHỌN *: Nếu bạn có các yêu cầu đặc biệt và tạo môi trường động khi thêm hoặc xóa cột sẽ tự động xử lý theo mã ứng dụng. Trong trường hợp đặc biệt này, bạn không yêu cầu thay đổi mã ứng dụng và cơ sở dữ liệu và điều này sẽ tự động ảnh hưởng đến môi trường sản xuất. Trong trường hợp này, bạn có thể sử dụng LỰA CHỌN * CHỌN.


0

Chỉ để thêm một sắc thái cho cuộc thảo luận mà tôi không thấy ở đây: Về I / O, nếu bạn đang sử dụng cơ sở dữ liệu với bộ lưu trữ hướng theo cột, bạn có thể thực hiện RẤT NHIỀU I / O nếu bạn chỉ truy vấn chắc chắn cột. Khi chúng tôi chuyển sang SSD, các lợi ích có thể nhỏ hơn một chút so với lưu trữ theo hướng hàng nhưng có một) chỉ đọc các khối có chứa các cột bạn quan tâm về b) nén, điều này thường làm giảm đáng kể kích thước của dữ liệu trên đĩa và do đó khối lượng dữ liệu đọc từ đĩa.

Nếu bạn không quen thuộc với lưu trữ theo định hướng cột, một triển khai cho Postgres đến từ Dữ liệu Citus, một cách khác là Greenplum, một Paraccel khác, một cách khác (nói một cách lỏng lẻo) là Amazon Redshift. Đối với MySQL có Infobright, InfiniDB hiện không còn tồn tại. Các dịch vụ thương mại khác bao gồm Vertica từ HP, Sybase IQ, Teradata ...


-1
select * from table1 INTERSECT  select * from table2

công bằng

select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )

Bạn có thể vui lòng định dạng mã của mình bằng cách tô sáng mã đó và nhấn Ctrl + K
WhatsThePoint
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.