Database
 sql >> база данни >  >> RDS >> Database

Разделяне на струни:последващо действие

Имаше много коментари след публикацията ми миналата седмица относно разделянето на низове. Мисля, че смисълът на статията не беше толкова очевиден, колкото би могъл да бъде:че прекарването на много време и усилия, опитвайки се да "усъвършенствате" по своята същност бавна функция за разделяне, базирана на T-SQL, няма да бъде от полза. Оттогава събрах най-новата версия на функцията за разделяне на низове на Джеф Модън и я противопоставих на останалите:

ALTER FUNCTION [dbo].[DelimitedSplitN4K]
(@pString NVARCHAR(4000), @pDelimiter NCHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
  WITH E1(N) AS (
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
  ),
  E2(N) AS (SELECT 1 FROM E1 a, E1 b),
  E4(N) AS (SELECT 1 FROM E2 a, E2 b), 
  cteTally(N) AS (SELECT TOP (ISNULL(DATALENGTH(@pString)/2,0)) 
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4),
  cteStart(N1) AS (SELECT 1 UNION ALL 
    SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
  ),
cteLen(N1,L1) AS(SELECT s.N1,
    ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,4000)
    FROM cteStart s
  )
 SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
        Item       = SUBSTRING(@pString, l.N1, l.L1)
   FROM cteLen l;
GO

(Единствените промени, които направих:форматирах го за показване и премахнах коментарите. Можете да извлечете оригиналния източник тук.)

Трябваше да направя няколко корекции в тестовете си, за да представя справедливо функцията на Джеф. Най-важното:трябваше да изхвърля всички проби, които включват низове> 4000 знака. Затова промених низовете от 5000 знака в таблицата dbo.strings, за да бъдат 4000 знака вместо това и се фокусирах само върху първите три не-MAX сценария (запазване на предишните резултати за първите два и стартиране на третите тестове отново за новия дължина на низовете от 4000 знака). Също така изпуснах таблицата с числата от всички тестове освен един, защото беше ясно, че производителността там винаги е била по-лоша с коефициент поне 10. Следващата диаграма показва отново изпълнението на функциите във всеки от четирите теста средно за 10 стартирания и винаги със студен кеш и чисти буфери.

И така, ето моите леко преработени предпочитани методи за всеки тип задача:

Ще забележите, че CLR остана моят избор, освен в единия случай, когато разделянето няма смисъл. И в случаите, когато CLR не е опция, методите XML и CTE обикновено са по-ефективни, освен в случай на разделяне на единична променлива, където функцията на Джеф може да бъде най-добрият вариант. Но като се има предвид, че може да се наложи да поддържам повече от 4000 знака, решението на таблицата Numbers просто може да се върне в списъка ми в специфични ситуации, в които нямам право да използвам CLR.

Обещавам, че следващата ми публикация, включваща списъци, изобщо няма да говори за разделяне чрез T-SQL или CLR и ще демонстрира как да опрости този проблем, независимо от типа данни.

Като настрана забелязах този коментар в една от версиите на функциите на Джеф, която беше публикувана в коментарите:Благодаря и на този, който е написал първата статия, която някога видях за „таблици с числа“, която се намира на следния URL адрес и на Адам Мачаник че ме доведе до него преди много години.
http://web.archive.org/web/20150411042510/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an -auxiliary-numbers-table.html


Тази статия е написана от мен през 2004 г. Така че който и да е добавил коментара към функцията, добре дошъл. :-)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да станете дизайнер на бази данни

  2. Най-добрите подходи за групирани общи суми

  3. 10 най-добри стартиращи фирми в облака – 2018 г

  4. Обработка на потвърждение по имейл по време на регистрация в Flask

  5. Как да поръчам по брой в SQL?