Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Vui lòng trợ giúp với các cải tiến STRING_SPLIT

Chúng tôi đang ở giữa chu kỳ giữa các bản phát hành và chúng tôi vẫn chưa nghe về bất kỳ tính năng nào được lên kế hoạch cho SQL Server vNext. Đây có lẽ là thời điểm tốt nhất để thúc ép Microsoft cải tiến, miễn là chúng tôi có thể phản hồi các yêu cầu của mình với các trường hợp kinh doanh hợp pháp. Trong SQL Server 2016, STRING_SPLIT đã giải quyết một khoảng trống còn thiếu từ lâu trong một ngôn ngữ mà phải thừa nhận là không dành cho việc xử lý chuỗi phức tạp. Và đó là điều tôi muốn đưa ra hôm nay.

Trong nhiều năm trước SQL Server 2016 (và trong nhiều năm kể từ đó), chúng tôi đã viết các phiên bản của riêng mình, cải thiện chúng theo thời gian và thậm chí tranh cãi xem ai là nhanh nhất. Chúng tôi viết blog về từng micro giây mà chúng tôi có thể đạt được và tôi, vì một người, đã nói nhiều lần, "đây là bài đăng cuối cùng của tôi về việc tách chuỗi!" Tuy nhiên, chúng tôi đang ở đây.

Tôi sẽ luôn tranh luận rằng các tham số có giá trị trong bảng là cách thích hợp để ngắt các chuỗi. Nhưng trong khi I tin rằng các đốm văn bản được phân tách bằng dấu phẩy này sẽ không bao giờ được hiển thị trong cơ sở dữ liệu ở dạng đó, việc tách chuỗi tiếp tục là một trường hợp sử dụng phổ biến - một vài bài đăng trên blog của tôi ở đây nằm trong top 5 về lượt xem mỗi ngày .

Vì vậy, tại sao mọi người vẫn cố gắng chia chuỗi với các hàm có giá trị bảng khi tồn tại một sự thay thế vượt trội? Tôi chắc chắn một số vì chúng vẫn đang ở phiên bản cũ hơn, bị mắc kẹt ở mức độ tương thích cũ hơn hoặc không thể thoát khỏi việc tách chuỗi vì TVP không được hỗ trợ bởi ngôn ngữ hoặc ORM của chúng. Đối với phần còn lại, trong khi STRING_SPLIT vừa tiện lợi vừa hiệu quả, nó không phải là hoàn hảo. Nó có những hạn chế gây ra một số khó khăn và khiến việc thay thế các lệnh gọi hàm hiện có bằng một lệnh gọi nguyên bản trở nên cồng kềnh hoặc không thể thực hiện được.

Đây là danh sách của tôi.

Những hạn chế này không phải là đầy đủ, nhưng tôi đã liệt kê những hạn chế quan trọng trong của tôi thứ tự ưu tiên (và Andy Mallon cũng đã viết blog về điều này ngày hôm nay):

  • Dấu phân cách một ký tự Có vẻ như hàm được tạo ra chỉ với trường hợp sử dụng đơn giản nhất:CSV. Mọi người có nhiều chuỗi phức tạp hơn 1,2,3 hoặc A | B | C và chúng thường được cung cấp cho cơ sở dữ liệu từ các hệ thống nằm ngoài tầm kiểm soát của chúng. Như tôi mô tả trong câu trả lời này và mẹo này, có nhiều cách để giải quyết vấn đề này (các hoạt động thay thế thực sự không hiệu quả), nhưng chúng thực sự xấu xí và khá thẳng thắn, hoàn tác tất cả các lợi ích hiệu suất được cung cấp bởi triển khai gốc. Ngoài ra, một số vấn đề với vấn đề này đặc biệt xuất phát từ:"Chà, string_to_array của PostgreSQL xử lý nhiều dấu phân tách ký tự, vậy tại sao SQL Server không thể? "Triển khai:Tăng kích thước tối đa của dấu phân tách .
  • Không có dấu hiệu về thứ tự đầu vào Đầu ra của hàm là một tập hợp và vốn dĩ, các tập hợp không có thứ tự. Và trong hầu hết các trường hợp, bạn sẽ thấy một chuỗi đầu vào như bob, ted, Frank ra theo thứ tự đó ( bob ted Frank ), không có gì đảm bảo (có hoặc không có (ORDER BY (SELECT NULL)) cẩu thả gian lận). Nhiều hàm được tạo tại nhà bao gồm một cột đầu ra để chỉ ra vị trí thứ tự trong chuỗi, điều này có thể quan trọng nếu danh sách được sắp xếp theo một thứ tự xác định hoặc vị trí thứ tự chính xác có một số ý nghĩa. đầu ra.
  • Loại đầu ra chỉ dựa trên đầu vào
    Cột đầu ra của hàm được cố định thành varchar hoặc nvarchar , và được xác định chính xác bằng độ dài của toàn bộ chuỗi đầu vào, không phải độ dài của phần tử dài nhất. Vì vậy, bạn có một danh sách gồm 25 chữ cái, kiểu đầu ra là ít nhất varchar (51) . Đối với các chuỗi dài hơn, điều này có thể giải quyết vấn đề với cấp bộ nhớ, tùy thuộc vào việc sử dụng và có thể gây ra sự cố nếu người dùng dựa vào một kiểu dữ liệu khác đang được xuất (giả sử, int , những hàm nào đôi khi chỉ định để tránh chuyển đổi ngầm định sau này). Để giải quyết vấn đề này, người dùng đôi khi tạo bảng tạm thời hoặc biến bảng của riêng họ và kết xuất đầu ra của hàm ở đó trước khi tương tác với nó, điều này có thể dẫn đến các vấn đề về hiệu suất. .
  • Không thể bỏ qua các phần tử trống hoặc dấu phân cách ở cuối
    Khi bạn có một chuỗi như a ,,, b, , bạn có thể mong đợi chỉ có hai phần tử được xuất ra, vì ba phần tử còn lại trống. Hầu hết các TVF tùy chỉnh mà tôi đã thấy đều cắt bỏ các dấu phân cách ở cuối và / hoặc lọc ra các chuỗi có độ dài bằng 0, nhưng STRING_SPLIT trả về tất cả 5 hàng. Điều này gây khó khăn cho việc hoán đổi trong hàm gốc vì bạn cũng phải thêm logic gói để loại bỏ các thực thể này.
  • Không thể lọc các bản sao
    Đây có lẽ là một yêu cầu ít phổ biến hơn và dễ giải quyết bằng cách sử dụng DISTINCT hoặc GROUP BY , nhưng rất nhiều chức năng tự động làm việc này cho bạn. Không có sự khác biệt thực sự về hiệu suất trong những trường hợp này, nhưng có điều gì đó nếu bạn quên thêm chính mình (hãy nghĩ đến một danh sách lớn, với nhiều bản sao, tham gia vào một bảng lớn).

    Triển khai:Thêm một tùy chọn để lọc ra các bản sao.

Đây là trường hợp kinh doanh.

Tất cả những điều đó nghe có vẻ lý thuyết, nhưng đây là trường hợp kinh doanh, mà tôi có thể đảm bảo với bạn là rất thực tế. Tại Wayfair, chúng tôi có một tài sản SQL Server đáng kể và chúng tôi thực sự có hàng chục nhóm khác nhau, những người đã tạo ra các hàm có giá trị bảng của riêng họ trong những năm qua. Một số tốt hơn những cái khác, nhưng tất cả chúng đều được gọi từ hàng nghìn hàng nghìn dòng mã. Gần đây, chúng tôi đã bắt đầu một dự án trong đó chúng tôi đang cố gắng thay thế chúng bằng các lệnh gọi tới STRING_SPLIT , nhưng chúng tôi đã gặp phải các trường hợp chặn liên quan đến một số hạn chế ở trên.

Một số dễ sử dụng, sử dụng hàm wrapper. Nhưng dấu phân cách ký tự đơn giới hạn buộc chúng tôi phải đánh giá giải pháp tồi tệ bằng cách sử dụng REPLACE , và điều này đã chứng minh là loại bỏ lợi ích hiệu suất mà chúng tôi mong đợi, khiến chúng tôi phải bơm phanh. Và trong những trường hợp đó, chúng tôi đã mất một con bài thương lượng quan trọng trong việc thúc đẩy nâng cấp lên mức độ tương thích (không phải tất cả cơ sở dữ liệu đều trên 130, đừng bận tâm đến 140). Trong những trường hợp đó, chúng tôi không chỉ thua ở STRING_SPLIT cải tiến, mà còn trên hơn 130 cải tiến hiệu suất khác mà chúng tôi sẽ tận hưởng nếu STRING_SPLIT tự nó đã đủ hấp dẫn để thúc đẩy nâng cấp cấp độ tính toán.

Vì vậy, tôi đang nhờ bạn giúp đỡ.

Vui lòng truy cập mục phản hồi này:

  • STRING_SPLIT chưa hoàn thành tính năng

Bỏ phiếu cho nó! Quan trọng hơn, hãy để lại nhận xét mô tả các trường hợp sử dụng thực tế mà bạn có tạo ra STRING_SPLIT một nỗi đau hoặc một khởi đầu cho bạn. Chỉ số phiếu bầu là không đủ nhưng với đủ phản hồi hữu hình và chất lượng, có khả năng họ sẽ bắt đầu xem xét những khoảng cách này một cách nghiêm túc.

Tôi cảm thấy muốn hỗ trợ các dấu phân cách nhiều ký tự (thậm chí, có thể mở rộng từ [n] varchar (1) thành [n] varchar (5) ) là một cải tiến đơn giản sẽ bỏ qua nhiều người chia sẻ kịch bản của tôi. Các cải tiến khác có thể khó thực hiện hơn, một số yêu cầu quá tải và / hoặc cải tiến ngôn ngữ, vì vậy tôi không mong đợi tất cả các bản sửa lỗi này trong vNext. Nhưng ngay cả một cải tiến nhỏ cũng sẽ nhắc lại rằng STRING_SPLIT là một khoản đầu tư đáng giá và nó sẽ không bị bỏ rơi (chẳng hạn như cơ sở dữ liệu chứa cơ sở dữ liệu, một trong những tính năng drive-by nổi tiếng hơn).

Cảm ơn đã lắng nghe!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Di chuyển cơ sở dữ liệu sang cơ sở dữ liệu SQL Azure

  2. Đánh giá sách:Benjamin Nevarez:Điều chỉnh &Tối ưu hóa Truy vấn

  3. Cầu nối RDBMS và NoSQL:Giới thiệu về cụm giao diện người dùng 2DX

  4. Giới thiệu về HDFS | HDFS là gì và nó hoạt động như thế nào?

  5. Cái giá của việc không thanh trừng