Cái nào nhanh hơn / tốt nhất? CHỌN * hoặc CHỌN cột1, colum2, cột3, v.v.


166

Tôi đã nghe nói rằng đó SELECT *là cách thực hành tồi để sử dụng khi viết các lệnh SQL vì nó hiệu quả hơn đối với SELECTcác cột mà bạn đặc biệt cần.

Nếu tôi cần SELECTmỗi cột trong một bảng, tôi có nên sử dụng

SELECT * FROM TABLE

hoặc là

SELECT column1, colum2, column3, etc. FROM TABLE

Liệu hiệu quả thực sự quan trọng trong trường hợp này? Tôi nghĩ rằng SELECT *sẽ tối ưu hơn trong nội bộ nếu bạn thực sự cần tất cả dữ liệu, nhưng tôi đang nói điều này mà không có sự hiểu biết thực sự về cơ sở dữ liệu.

Tôi tò mò muốn biết thực hành tốt nhất là gì trong trường hợp này.

CẬP NHẬT: Tôi có lẽ nên xác định rằng tình huống duy nhất mà tôi thực sự sẽ muốn làm SELECT *là khi tôi chọn dữ liệu từ một bảng trong đó tôi biết tất cả các cột sẽ luôn cần phải được truy xuất, ngay cả khi các cột mới được thêm vào.

Tuy nhiên, với những phản hồi mà tôi đã thấy, đây vẫn có vẻ là một ý tưởng tồi và SELECT *không bao giờ nên được sử dụng vì nhiều lý do kỹ thuật mà tôi từng nghĩ đến.




1
Vâng, đó là một bản sao của hầu hết những người.
George

Câu trả lời:


168

Một lý do khiến việc chọn các cột cụ thể tốt hơn là vì nó làm tăng xác suất SQL Server có thể truy cập dữ liệu từ các chỉ mục thay vì truy vấn dữ liệu bảng.

Đây là một bài tôi đã viết về nó: Lý do thực sự của các truy vấn chọn là phạm vi chỉ số xấu

Nó cũng ít dễ thay đổi hơn, vì bất kỳ mã nào sử dụng dữ liệu sẽ có cùng cấu trúc dữ liệu bất kể thay đổi bạn thực hiện đối với lược đồ bảng trong tương lai.


3
+1 cho điều này. Nếu tất cả các cột được tham chiếu tồn tại trong một chỉ mục ("chỉ số che phủ"), bạn đã đạt được vàng.
Ian Nelson

22
đó không phải là câu trả lời cho câu hỏi của anh ấy - "Nếu tôi cần CHỌN mỗi cột trong một bảng, ..." - trong trường hợp đó, * so với col1, .., coln không thành vấn đề (nhưng nó KHÔNG cho thời gian lập trình viên, vì * ngắn hơn!).
Matt Rogish

3
Nó vẫn là vấn đề, bởi vì danh sách chọn là một dạng hợp đồng, đặc biệt nếu SQL nằm trong một thủ tục được lưu trữ.
Râu Eric Z

4
Trong khi những gì Jon nói là hoàn toàn chính xác, và một điểm rất hợp lệ, tôi phải đồng ý rằng câu hỏi AS ASKED là về nếu họ đã yêu cầu tất cả các cột. Do phần này của câu hỏi, vấn đề thực sự là sự mong manh khi đối mặt với những thay đổi của lược đồ.
IDis Dùng

1
@MattRogish thưa bạn, bạn đã hiểu đúng, có sự khác biệt về hiệu năng giữa hai phương thức này (* vsall_column_names) trong khi chúng tôi có hàng ngàn hàng và chúng tôi thực hiện CHỌN với chỉ mục (trong mệnh đề WHERE) ??
santosh

59

Với đặc điểm kỹ thuật của bạn rằng bạn đang chọn tất cả các cột, có rất ít sự khác biệt tại thời điểm này . Tuy nhiên, nhận ra rằng các lược đồ cơ sở dữ liệu thay đổi. Nếu bạn dùngSELECT * bạn sẽ nhận được bất kỳ cột mới nào được thêm vào bảng, mặc dù trong tất cả khả năng, mã của bạn không được chuẩn bị để sử dụng hoặc trình bày dữ liệu mới đó. Điều này có nghĩa là bạn đang phơi bày hệ thống của mình trước những thay đổi về hiệu năng và chức năng không mong muốn.

Bạn có thể sẵn sàng loại bỏ điều này như một chi phí nhỏ, nhưng nhận ra rằng các cột mà bạn không cần vẫn phải là:

  1. Đọc từ cơ sở dữ liệu
  2. Gửi qua mạng
  3. Tham gia vào quá trình của bạn
  4. (đối với công nghệ loại ADO) Được lưu trong bảng dữ liệu trong bộ nhớ
  5. Bỏ qua và loại bỏ / thu gom rác

Mục số 1 có nhiều chi phí ẩn bao gồm loại bỏ một số chỉ số che phủ tiềm năng, gây ra tải trang dữ liệu (và đập bộ đệm máy chủ), phát sinh khóa hàng / trang / bảng có thể tránh được.

Cân bằng điều này với mức tiết kiệm tiềm năng của việc chỉ định các cột so với *và tiết kiệm tiềm năng duy nhất là:

  1. Lập trình viên không cần phải xem lại SQL để thêm các cột
  2. Truyền tải mạng của SQL nhỏ hơn / nhanh hơn
  3. Thời gian xác thực / phân tích truy vấn SQL Server
  4. Bộ đệm truy vấn SQL Server

Đối với mục 1, thực tế là bạn sẽ thêm / thay đổi mã để sử dụng bất kỳ cột mới nào bạn có thể thêm vào, vì vậy đây là một rửa.

Đối với mục 2, sự khác biệt hiếm khi đủ để đẩy bạn vào một gói hoặc số gói mạng khác nhau. Nếu bạn đi đến điểm mà thời gian truyền câu lệnh SQL là vấn đề chính, có lẽ bạn cần phải giảm tốc độ của câu lệnh trước.

Đối với mục 3, KHÔNG có khoản tiết kiệm nào vì việc mở rộng *phải xảy ra bằng mọi cách, điều đó có nghĩa là tham khảo lược đồ (các) bảng. Trên thực tế, việc liệt kê các cột sẽ phải chịu cùng một chi phí vì chúng phải được xác nhận theo lược đồ. Nói cách khác, đây là một rửa hoàn toàn.

Đối với mục 4, khi bạn chỉ định các cột cụ thể, bộ đệm của kế hoạch truy vấn của bạn có thể lớn hơn nhưng chỉ khi bạn đang xử lý các nhóm cột khác nhau (không phải là những gì bạn đã chỉ định). Trong trường hợp này, bạn muốn các mục bộ đệm khác nhau vì bạn muốn các gói khác nhau khi cần.

Vì vậy, tất cả điều này xảy ra, bởi vì cách bạn đã chỉ định câu hỏi, cho khả năng phục hồi vấn đề khi đối mặt với các sửa đổi lược đồ cuối cùng. Nếu bạn đang ghi lược đồ này vào ROM (nó xảy ra), thì điều đó *là hoàn toàn chấp nhận được.

Tuy nhiên, hướng dẫn chung của tôi là bạn chỉ nên chọn các cột bạn cần, điều đó có nghĩa là đôi khi nó sẽ giống như bạn đang yêu cầu tất cả chúng, nhưng các DBA và tiến hóa lược đồ có nghĩa là một số cột mới có thể ảnh hưởng lớn đến truy vấn .

Lời khuyên của tôi là bạn LUÔN LUÔN CHỌN các cột cụ thể . Hãy nhớ rằng bạn giỏi về những gì bạn làm đi làm lại, vì vậy hãy tập thói quen làm đúng.

Nếu bạn đang tự hỏi tại sao một lược đồ có thể thay đổi mà không thay đổi mã, hãy nghĩ về việc ghi nhật ký kiểm toán, ngày hiệu lực / ngày hết hạn và những thứ tương tự khác được DBA thêm vào cho các vấn đề tuân thủ một cách có hệ thống. Một nguồn thay đổi ngầm khác là sự không chuẩn hóa cho hiệu suất ở những nơi khác trong hệ thống hoặc các trường do người dùng xác định.


3
"thực tế là bạn sẽ thêm / thay đổi mã để sử dụng bất kỳ cột mới nào mà bạn có thể thêm vào, vì vậy đây là một sự tẩy rửa." -Chỉ khi bạn đọc thủ công từng cột theo tên trong mã của bạn. Nếu bạn đang sử dụng ánh xạ tự động, đây không phải là trường hợp và vấn đề này trở nên quan trọng.
Josh Noe

36

Bạn chỉ nên chọn các cột mà bạn cần. Ngay cả khi bạn cần tất cả các cột, vẫn nên liệt kê các tên cột để máy chủ sql không phải truy vấn bảng hệ thống cho các cột.

Ngoài ra, ứng dụng của bạn có thể bị hỏng nếu ai đó thêm các cột vào bảng. Chương trình của bạn sẽ nhận được các cột mà nó không mong đợi quá và nó có thể không biết cách xử lý chúng.

Ngoài ra, nếu bảng có cột nhị phân thì truy vấn sẽ chậm hơn nhiều và sử dụng nhiều tài nguyên mạng hơn.


6
Aha vì vậy bằng cách sử dụng * bạn đang thêm công việc bổ sung cho DB. Ok đó là một lý do tôi đã không nghĩ đến.
Ankur

1
+1 cho rủi ro phá / bắt lỗi sớm. Tôi nghĩ rằng các cuộc thảo luận về hiệu quả là hợp lệ nhưng YAGNI.
đinh vào

6
Máy chủ SQL có cần xác thực hoặc kiểm tra xem "col1" có trong bảng được chỉ định hay không, tức là bảng hệ thống truy vấn?
Patrick

3
Hit hiệu suất lớn nhất có lẽ liên quan đến lập chỉ mục. Nếu cột bạn đang tìm là một phần của chỉ mục được sử dụng để tìm dữ liệu, máy chủ sẽ tìm nạp dữ liệu ngay tại đó, nếu bạn chọn * rất có thể sẽ phải thực hiện cái được gọi là tra cứu dấu trang, yêu cầu thêm quét để tìm phần còn lại của dữ liệu cơ bản mà bạn có thể không cần.
Cobusve

3
@Patrick - Phát hiện. Rất nhiều lý do tốt để tránh * nhưng đó không phải là một trong số đó.
Martin Smith

31

Có bốn lý do lớn select *là một điều xấu:

  1. Lý do thực tế quan trọng nhất là nó buộc người dùng phải biết một cách kỳ diệu thứ tự các cột sẽ được trả về. Tốt hơn hết là nên nói rõ, điều này cũng bảo vệ bạn trước sự thay đổi của bảng, điều này giúp phân biệt thành ...

  2. Nếu tên cột bạn đang sử dụng thay đổi, tốt hơn là nên bắt sớm (tại điểm gọi SQL) thay vì khi bạn đang cố sử dụng cột không còn tồn tại (hoặc đã thay đổi tên, v.v. )

  3. Liệt kê các tên cột làm cho mã của bạn tự ghi lại nhiều hơn và do đó có thể dễ đọc hơn.

  4. Nếu bạn chuyển qua mạng (hoặc thậm chí nếu bạn không), các cột bạn không cần chỉ là lãng phí.


7
"Lý do thực tế quan trọng nhất là nó buộc người dùng phải biết một cách kỳ diệu thứ tự các cột sẽ được trả về." Tôi không thấy đây là một vấn đề. Trong bất kỳ máy khách DB hiện đại nào, bạn đọc các cột theo tên, không theo thứ tự.
Josh Noe

Tôi có xu hướng chạy SQL của mình thông qua giao diện C, vì vậy tôi thực sự không biết trạng thái của nghệ thuật trong "máy khách DB" là gì. Nhưng tôi nghĩ có lẽ loại khách hàng mà bạn đang nói đến đang thực hiện một số phép thuật phi SQL không chuẩn. (ví dụ: trong SQLite, truy vấn sqlite3_master để tìm ra cách thay đổi tên của bạn *thành một tập hợp các tên.)
pkh

Và hơn nữa từ đây có bao nhiêu người viết mã trong các ứng dụng hiện đại sử dụng chỉ mục của tên cột? Hầu hết mọi người chắc chắn đang sử dụng một số loại trình ánh xạ và cả đống bộ nhớ đệm cho dữ liệu được phép cũ. Cá nhân, viết mã trước, và sau đó lo lắng nếu bạn có vấn đề về hiệu suất sau này.
Colin Wiseman

10

Chỉ định danh sách cột thường là tùy chọn tốt nhất vì ứng dụng của bạn sẽ không bị ảnh hưởng nếu ai đó thêm / chèn một cột vào bảng.


7

Chỉ định tên cột chắc chắn là nhanh hơn - cho máy chủ. Nhưng nếu

  1. hiệu suất không phải là một vấn đề lớn (ví dụ: đây là cơ sở dữ liệu nội dung trang web với hàng trăm, có thể hàng ngàn - nhưng không phải hàng triệu - hàng trong mỗi bảng); VÀ
  2. công việc của bạn là tạo ra nhiều ứng dụng nhỏ, tương tự (ví dụ: các trang web được quản lý nội dung công khai) bằng cách sử dụng một khung chung, thay vì tạo một ứng dụng một lần phức tạp; VÀ
  3. tính linh hoạt là rất quan trọng (rất nhiều tùy chỉnh của lược đồ db cho từng trang web);

sau đó tốt hơn hết là bạn nên gắn bó với CHỌN *. Trong khuôn khổ của chúng tôi, việc sử dụng CHỌN * cho phép chúng tôi giới thiệu trường nội dung được quản lý trang web mới vào một bảng, mang lại cho nó tất cả các lợi ích của CMS (phiên bản, quy trình làm việc / phê duyệt, v.v.), trong khi chỉ chạm vào mã tại vài điểm, thay vì vài chục điểm.

Tôi biết các bậc thầy về DB sẽ ghét tôi vì điều này - hãy tiếp tục, bỏ phiếu cho tôi - nhưng trong thế giới của tôi, thời gian của nhà phát triển rất khan hiếm và chu kỳ CPU rất phong phú, vì vậy tôi điều chỉnh theo những gì tôi bảo tồn và những gì tôi lãng phí.


1
Nó cũng làm cho ORM đơn giản hơn nhiều để sử dụng. Khi các truy vấn được xây dựng bằng cách chuyển một đối tượng xây dựng truy vấn xung quanh, người ta không nhất thiết phải biết các cột nào được yêu cầu bởi các phần khác của mã (kiểm tra quyền, bạn có gì). Vì vậy, để giới hạn các cột, người ta sẽ cần điều tra mỗi khi truy vấn cần viết. Điều này là vô nghĩa, IMO. Khi các truy vấn hóa ra là chậm (nhật ký!), Người ta có thể cải thiện những truy vấn đó.
bytepizer

6

CHỌN * là một thực tiễn xấu ngay cả khi truy vấn không được gửi qua mạng.

  1. Chọn nhiều dữ liệu hơn bạn cần làm cho truy vấn kém hiệu quả hơn - máy chủ phải đọc và truyền thêm dữ liệu, do đó sẽ mất thời gian và tạo tải không cần thiết trên hệ thống (không chỉ mạng, như những người khác đã đề cập, mà cả đĩa, CPU, v.v. ). Ngoài ra, máy chủ không thể tối ưu hóa truy vấn cũng như có thể (ví dụ: sử dụng chỉ mục che cho truy vấn).
  2. Sau một thời gian, cấu trúc bảng của bạn có thể thay đổi, vì vậy CHỌN * sẽ trả về một nhóm cột khác. Vì vậy, ứng dụng của bạn có thể nhận được một tập dữ liệu về cấu trúc không mong muốn và phá vỡ ở đâu đó. Việc nêu rõ các cột đảm bảo rằng bạn có được một tập dữ liệu về cấu trúc đã biết hoặc nhận được một lỗi rõ ràng ở cấp cơ sở dữ liệu (như 'không tìm thấy cột').

Tất nhiên, tất cả điều này không quan trọng lắm đối với một hệ thống nhỏ và đơn giản.


4

Hiệu suất khôn ngoan, CHỌN với các cột cụ thể có thể nhanh hơn (không cần đọc trong tất cả dữ liệu). Nếu truy vấn của bạn thực sự sử dụng TẤT CẢ các cột, thì CHỌN với các tham số rõ ràng vẫn được ưu tiên. Bất kỳ sự khác biệt về tốc độ sẽ về cơ bản là không đáng chú ý và gần thời gian liên tục. Một ngày nào đó lược đồ của bạn sẽ thay đổi, và đây là bảo hiểm tốt để ngăn chặn các vấn đề do điều này.


Bạn đã sai về sự không chú ý vì từ các kiểm tra tôi đã thực hiện với một số DB, rõ ràng việc chọn từng cột, ngay cả khi tất cả chúng, nhanh hơn nhiều. Trong một số trường hợp, nó nhanh hơn ba lần.
shahar eldad

4

Rất nhiều lý do chính đáng được trả lời ở đây cho đến nay, đây là một lý do khác chưa được đề cập.

Đặt tên rõ ràng cho các cột sẽ giúp bạn bảo trì xuống đường. Tại một số điểm, bạn sẽ thực hiện thay đổi hoặc khắc phục sự cố và thấy mình hỏi "cột đó được sử dụng ở đâu".

Nếu bạn đã có tên được liệt kê rõ ràng, thì việc tìm mọi tham chiếu đến cột đó - thông qua tất cả các quy trình, chế độ xem được lưu trữ, v.v. - rất đơn giản. Chỉ cần kết xuất tập lệnh CREATE cho lược đồ DB của bạn và tìm kiếm văn bản thông qua nó.


3

chắc chắn xác định các cột, bởi vì SQL Server sẽ không phải tìm kiếm trên các cột để kéo chúng. Nếu bạn xác định các cột, thì SQL có thể bỏ qua bước đó.


Đây là: 1) không liên quan, bởi vì SQL Server phải tham chiếu lược đồ bảng theo bất kỳ cách nào (để xác thực tên cột hoặc tìm kiếm tên cột hợp lệ đã biết) 2) Không liên quan đến câu hỏi được hỏi, trong đó tất cả các cột đang được tham chiếu. Vấn đề duy nhất NHƯ ASKED là sự thay đổi lược đồ w / lược đồ.
IDis Dùng

Bị đánh giá thấp, bởi vì nó phải xác nhận các cột bất kể.
John Gibb

3

Luôn luôn tốt hơn để chỉ định các cột bạn cần, nếu bạn nghĩ về nó một lần, SQL không phải nghĩ "wtf là *" mỗi khi bạn truy vấn. Trên hết, ai đó sau này có thể thêm các cột vào bảng mà bạn thực sự không cần trong truy vấn của mình và bạn sẽ tốt hơn trong trường hợp đó bằng cách chỉ định tất cả các cột của mình.


1
Điều này không đúng: Máy chủ SQL vẫn phải phân tích từng cột và xem liệu nó có tồn tại trong danh mục hay không, trong khi nó biết rằng "*" không (và có, * được mở rộng cho tất cả các cols). Dù bằng cách nào, DBMS cũng dễ dàng thực hiện một trong hai cách (trừ khi bạn có 24.000 cột), vì vậy tôi cá là nó cũng vậy
Matt Rogish

Tôi nghĩ rằng điểm tốt hơn là nhiều người bị thiếu và thật không may, câu trả lời này chỉ giải quyết tạm thời, là nếu thay đổi lược đồ / bảng (nghĩa là các cột mới được thêm vào) thì nó sẽ không phá vỡ mọi thứ.
Sean Hanley

1
Đó là một sự rửa sạch hoàn toàn khi tra cứu các cột cho bản mở rộng * cũng giống như xác nhận các tên cột được cung cấp.
IDis Dùng

3

Vấn đề với "select *" là khả năng mang lại dữ liệu bạn không thực sự cần. Trong truy vấn cơ sở dữ liệu thực tế, các cột được chọn không thực sự thêm vào tính toán. Điều thực sự "nặng nề" là việc truyền dữ liệu trở lại máy khách của bạn và bất kỳ cột nào bạn không thực sự cần chỉ là lãng phí băng thông mạng và thêm vào thời gian bạn chờ bạn truy vấn để trả về.

Ngay cả khi bạn sử dụng tất cả các cột được mang từ "select * ...", thì đó chỉ là bây giờ. Nếu trong tương lai bạn thay đổi bố cục bảng / dạng xem và thêm nhiều cột khác, bạn sẽ bắt đầu mang theo những thứ bạn chọn ngay cả khi bạn không cần chúng.

Một điểm khác trong đó một câu lệnh "select *" là xấu khi tạo chế độ xem. Nếu bạn tạo chế độ xem bằng cách sử dụng "select *" và sau đó thêm các cột vào bảng của mình, định nghĩa chế độ xem và dữ liệu được trả về sẽ không khớp và bạn sẽ cần biên dịch lại các chế độ xem của mình để chúng hoạt động trở lại.

Tôi biết rằng việc viết "chọn *" rất hấp dẫn, vì tôi thực sự không muốn chỉ định thủ công tất cả các trường trên các truy vấn của mình, nhưng khi hệ thống của bạn bắt đầu phát triển, bạn sẽ thấy rằng đáng để dành thêm thời gian này / nỗ lực trong việc chỉ định các lĩnh vực thay vì dành nhiều thời gian và nỗ lực hơn để loại bỏ các lỗi trên quan điểm của bạn hoặc tối ưu hóa ứng dụng của bạn.


Điểm trên XEM là rất quan trọng. Bạn không chỉ không nhận được tất cả các cột nếu bạn thêm các cột vào bảng (mặc dù những gì * sẽ khiến bạn nghĩ), nhưng chúng thậm chí có thể không khớp với bố cục thực của bảng.
Euro Micelli

3

Mặc dù các cột liệt kê rõ ràng là tốt cho hiệu suất, nhưng đừng có điên.

Vì vậy, nếu bạn sử dụng tất cả dữ liệu, hãy thử CHỌN * để đơn giản (hãy tưởng tượng có nhiều cột và thực hiện một truy vấn THAM GIA ... có thể trở nên khủng khiếp). Sau đó - đo lường. So sánh với truy vấn với tên cột được liệt kê rõ ràng.

Đừng suy đoán về hiệu suất, đo lường nó!

Danh sách rõ ràng giúp ích nhiều nhất khi bạn có một số cột chứa dữ liệu lớn (như nội dung của bài đăng hoặc bài viết) và không cần nó trong truy vấn nhất định. Sau đó, bằng cách không trả lại nó trong câu trả lời, máy chủ DB của bạn có thể tiết kiệm thời gian, băng thông và thông lượng đĩa. Kết quả truy vấn của bạn cũng sẽ nhỏ hơn, tốt cho mọi bộ đệm truy vấn.


3

Bạn thực sự chỉ nên chọn các lĩnh vực bạn cần và chỉ số lượng được yêu cầu, nghĩa là

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

Bên ngoài cơ sở dữ liệu, các truy vấn động có nguy cơ bị tấn công tiêm và dữ liệu không đúng định dạng. Thông thường, bạn có được vòng này bằng cách sử dụng các thủ tục được lưu trữ hoặc truy vấn tham số. Ngoài ra (mặc dù không thực sự có quá nhiều vấn đề), máy chủ phải tạo một kế hoạch thực hiện mỗi khi một truy vấn động được thực thi.


"Máy chủ phải tạo một kế hoạch thực hiện mỗi khi một truy vấn động được thực thi" mà tôi giả sử làm chậm truy vấn. Cảm ơn.
Ankur

Các vấn đề về hiệu năng của việc sử dụng sql động có lẽ chỉ được nhận ra trong các tình huống tải rất cao, Sql Server khá giỏi trong việc quản lý các kế hoạch truy vấn một cách hiệu quả.
Matthew Abbott

2

Chọn là hiệu quả tương đương (về vận tốc) nếu bạn sử dụng * hoặc cột.

Sự khác biệt là về bộ nhớ, không phải vận tốc. Khi bạn chọn một số cột, SQL Server phải phân bổ không gian bộ nhớ để phục vụ bạn truy vấn, bao gồm tất cả dữ liệu cho tất cả các cột mà bạn đã yêu cầu, ngay cả khi bạn chỉ sử dụng một trong số chúng.

Điều quan trọng về mặt hiệu suất là kế hoạch thực hiện, điều này phụ thuộc rất nhiều vào mệnh đề WHERE của bạn và số lượng THAM GIA, NGOÀI THAM GIA, v.v ...

Đối với câu hỏi của bạn chỉ cần sử dụng CHỌN *. Nếu bạn cần tất cả các cột thì không có sự khác biệt về hiệu suất.


2

KHÔNG nhanh hơn khi sử dụng tên trường rõ ràng so với *, nếu và chỉ khi, bạn cần lấy dữ liệu cho tất cả các trường.

Phần mềm máy khách của bạn không nên phụ thuộc vào thứ tự của các trường được trả về, do đó, điều đó cũng vô nghĩa.

Và có thể (mặc dù không chắc) rằng bạn cần có được tất cả các trường bằng cách sử dụng * vì bạn chưa biết trường nào tồn tại (nghĩ cấu trúc cơ sở dữ liệu rất động).

Một nhược điểm khác của việc sử dụng tên trường rõ ràng là nếu có nhiều tên trong số chúng và chúng dài thì việc đọc mã và / hoặc nhật ký truy vấn trở nên khó khăn hơn.

Vì vậy, quy tắc nên là: nếu bạn cần tất cả các trường, hãy sử dụng *, nếu bạn chỉ cần một tập hợp con, hãy đặt tên cho chúng một cách rõ ràng.


2

Kết quả là quá lớn. Việc tạo và gửi kết quả từ công cụ SQL đến máy khách là chậm.

Phía máy khách, là một môi trường lập trình chung, không và không nên được thiết kế để lọc và xử lý kết quả (ví dụ: mệnh đề WHERE, mệnh đề ORDER), vì số lượng hàng có thể rất lớn (ví dụ: hàng chục triệu hàng).


Vì vậy, nếu bạn thực sự cần sử dụng tất cả các cột khác nhau thì sẽ ổn thôi ... và nếu cơ sở dữ liệu và ứng dụng của bạn lại ngồi trên cùng một máy chủ, điều đó có khác biệt gì không?
Ankur

@Ankur: Ngay cả trên cùng một máy chủ cũng có chi phí để truyền dữ liệu qua giao diện cơ sở dữ liệu.
kennytm

2

Đặt tên cho mỗi cột mà bạn mong muốn nhận được trong ứng dụng của mình cũng đảm bảo ứng dụng của bạn sẽ không bị hỏng nếu có ai đó thay đổi bảng, miễn là các cột của bạn vẫn còn (theo bất kỳ thứ tự nào).


1

Nó phụ thuộc vào phiên bản máy chủ DB của bạn, nhưng các phiên bản SQL hiện đại có thể lưu trữ kế hoạch theo bất kỳ cách nào. Tôi muốn nói đi với bất cứ điều gì có thể duy trì nhất với mã truy cập dữ liệu của bạn.


1

Một lý do tốt hơn là bạn nên đánh vần chính xác cột nào bạn muốn là vì những thay đổi có thể xảy ra trong cấu trúc bảng.

Nếu bạn đang đọc dữ liệu theo cách thủ công bằng cách sử dụng cách tiếp cận dựa trên chỉ mục để điền vào cấu trúc dữ liệu với kết quả truy vấn của bạn, thì trong tương lai khi bạn thêm / xóa một cột, bạn sẽ phải đau đầu khi cố gắng tìm ra lỗi sai.

Đối với những gì nhanh hơn, tôi sẽ trì hoãn cho người khác về chuyên môn của họ.


1

Như với hầu hết các vấn đề, nó phụ thuộc vào những gì bạn muốn đạt được. Nếu bạn muốn tạo một lưới db sẽ cho phép tất cả các cột trong bất kỳ bảng nào, thì "Chọn *" là câu trả lời. Tuy nhiên, nếu bạn sẽ chỉ cần một số cột nhất định và việc thêm hoặc xóa các cột khỏi truy vấn được thực hiện không thường xuyên, sau đó chỉ định chúng riêng lẻ.

Nó cũng phụ thuộc vào lượng dữ liệu bạn muốn chuyển từ máy chủ. Nếu một trong các cột được xác định là ghi nhớ, đồ họa, blob, v.v. và bạn không cần cột đó, tốt nhất bạn không nên sử dụng "Chọn *" hoặc bạn sẽ nhận được cả đống dữ liệu mà bạn không muốn và hiệu suất của bạn có thể bị ảnh hưởng.


1

Để thêm vào những gì mọi người khác đã nói, nếu tất cả các cột mà bạn đang chọn được đưa vào một chỉ mục, tập kết quả của bạn sẽ được lấy từ chỉ mục thay vì tra cứu dữ liệu bổ sung từ SQL.


1

CHỌN * là cần thiết nếu một người muốn có được siêu dữ liệu, chẳng hạn như số lượng cột.


1

Những gì mọi người ở trên đã nói, cộng thêm:

Nếu bạn đang phấn đấu để có thể đọc được mã có thể bảo trì, hãy làm một cái gì đó như:

CHỌN foo, thanh TỪ các vật dụng;

là ngay lập tức có thể đọc và hiển thị ý định. Nếu bạn thực hiện cuộc gọi đó, bạn biết những gì bạn sẽ nhận lại. Nếu các widget chỉ có các cột foo và bar, thì việc chọn * có nghĩa là bạn vẫn phải suy nghĩ về những gì bạn sẽ nhận lại, xác nhận thứ tự được ánh xạ chính xác, v.v. Tuy nhiên, nếu các widget có nhiều cột hơn nhưng bạn chỉ quan tâm đến foo và thanh, sau đó mã của bạn trở nên lộn xộn khi bạn truy vấn ký tự đại diện và sau đó chỉ sử dụng một số thứ được trả về.


1

Và hãy nhớ nếu bạn có một phép nối bên trong theo định nghĩa, bạn không cần tất cả các cột vì dữ liệu trong các cột nối được lặp lại.

Nó không giống như các cột liệt kê trong máy chủ SQl là khó khăn hoặc thậm chí tốn thời gian. Bạn chỉ cần kéo chúng từ trình duyệt đối tượng (bạn có thể lấy tất cả trong một lần bằng cách kéo từ các cột từ). Để đạt được hiệu suất vĩnh viễn trên hệ thống của bạn (vì điều này có thể làm giảm việc sử dụng các chỉ mục và vì việc gửi dữ liệu không cần thiết qua mạng rất tốn kém) và có nhiều khả năng bạn sẽ gặp sự cố không mong muốn khi cơ sở dữ liệu thay đổi (đôi khi các cột được thêm vào bạn không muốn người dùng nhìn thấy chẳng hạn) chỉ để tiết kiệm ít hơn một phút thời gian phát triển là thiển cận và không chuyên nghiệp.


1

Hiệu suất khôn ngoan Tôi đã thấy ý kiến ​​rằng cả hai đều bằng nhau. nhưng khía cạnh khả năng sử dụng có một số + và

Khi bạn sử dụng (select *) trong truy vấn và nếu một số thay đổi bảng và thêm các trường mới không cần cho truy vấn trước đó thì đó là một chi phí không cần thiết. Và nếu trường mới được thêm vào là một đốm màu hoặc trường hình ảnh thì sao ??? thời gian phản hồi truy vấn của bạn sẽ rất chậm.

Mặt khác, nếu bạn sử dụng (chọn col1, col2, ..) và nếu bảng bị thay đổi và thêm các trường mới và nếu các trường đó là cần thiết trong tập kết quả, bạn luôn cần chỉnh sửa truy vấn đã chọn sau khi thay đổi bảng.

Nhưng tôi khuyên bạn nên luôn luôn sử dụng chọn col1, col2, ... trong các truy vấn của mình và thay đổi truy vấn nếu bảng bị thay đổi sau ...


0

Hoàn toàn xác định các cột bạn muốn CHỌN mỗi lần. Không có lý do gì để không và cải thiện hiệu suất là hoàn toàn xứng đáng.

Họ không bao giờ nên đưa ra tùy chọn "CHỌN *"


0

Nếu bạn cần mỗi cột thì chỉ cần sử dụng CHỌN * nhưng hãy nhớ rằng thứ tự có khả năng thay đổi để khi bạn tiêu thụ kết quả, hãy truy cập chúng theo tên chứ không phải theo chỉ mục.

Tôi sẽ bỏ qua các bình luận về cách * cần phải đi lấy danh sách - cơ hội phân tích cú pháp và xác thực các cột có tên bằng với thời gian xử lý nếu không nhiều hơn. Đừng tối ưu hóa sớm ;-)


0

Về hiệu quả thực hiện tôi không nhận thấy bất kỳ sự khác biệt đáng kể nào. Nhưng để hiệu quả cho lập trình viên, tôi sẽ viết tên của các trường vì

  • Bạn biết thứ tự nếu bạn cần lập chỉ mục theo số hoặc nếu trình điều khiển của bạn cư xử hài hước trên các giá trị blob và bạn cần một thứ tự xác định
  • Bạn chỉ đọc các trường bạn cần, nếu bạn nên thêm nhiều trường
  • Bạn gặp lỗi sql nếu bạn viết sai chính tả hoặc đổi tên trường, không phải giá trị trống từ recordset / row
  • Bạn có thể đọc tốt hơn những gì đang xảy ra.

0

này, hãy thực tế sử dụng select * khi tạo mẫu và chọn các cột cụ thể khi triển khai và triển khai. từ góc độ kế hoạch thực hiện, cả hai đều tương đối giống nhau trên các hệ thống hiện đại. tuy nhiên, việc chọn các cột cụ thể sẽ giới hạn lượng dữ liệu phải được truy xuất từ ​​đĩa, được lưu trong bộ nhớ và gửi qua mạng.

cuối cùng, kế hoạch tốt nhất là chọn các cột cụ thể.

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.