sql >> Database >  >> RDS >> Database

Strings splitsen:een vervolg

Er waren veel opmerkingen na mijn bericht van vorige week over het splitsen van strings. Ik denk dat het punt van het artikel niet zo duidelijk was als het had kunnen zijn:dat het niet nuttig zou zijn om veel tijd en moeite te besteden aan het "perfectioneren" van een inherent langzame splitsingsfunctie op basis van T-SQL. Sindsdien heb ik de meest recente versie van Jeff Modens functie voor het splitsen van strings verzameld en vergeleken met de andere:

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

(De enige wijzigingen die ik heb aangebracht:ik heb het geformatteerd voor weergave en ik heb de opmerkingen verwijderd. Je kunt de originele bron hier ophalen.)

Ik moest een paar aanpassingen aan mijn tests maken om Jeffs functie redelijk weer te geven. Het belangrijkste was:ik moest alle samples weggooien met strings> 4.000 karakters. Dus veranderde ik de 5.000 karakters strings in de dbo.strings tabel in 4.000 karakters, en concentreerde ik me alleen op de eerste drie niet-MAX scenario's (waarbij de vorige resultaten voor de eerste twee behouden blijven en de derde tests opnieuw uitvoeren voor de nieuwe stringlengtes van 4.000 tekens). Ik liet ook de Numbers-tabel van alle tests op één na, omdat het duidelijk was dat de prestaties daar altijd minstens een factor 10 slechter waren. De volgende grafiek toont de prestaties van de functies in elk van de vier tests, opnieuw gemiddeld over 10 runs en altijd met een koude cache en schone buffers.

Dus hier zijn mijn enigszins herziene voorkeursmethoden, voor elk type taak:

U zult merken dat CLR mijn voorkeursmethode is gebleven, behalve in het ene geval waarin splitsen geen zin heeft. En in gevallen waarin CLR geen optie is, zijn de XML- en CTE-methoden over het algemeen efficiënter, behalve in het geval van het splitsen van één variabele, waar de functie van Jeff misschien wel de beste optie is. Maar aangezien ik mogelijk meer dan 4.000 tekens moet ondersteunen, komt de Numbers-tabeloplossing misschien terug op mijn lijst in specifieke situaties waarin ik CLR niet mag gebruiken.

Ik beloof dat mijn volgende bericht met lijsten helemaal niet zal gaan over splitsen, via T-SQL of CLR, en zal laten zien hoe dit probleem kan worden vereenvoudigd, ongeacht het gegevenstype.

Even terzijde, ik merkte deze opmerking op in een van de versies van Jeff's functies die in de opmerkingen was geplaatst:omdat ze me er jaren geleden naartoe hebben geleid.
http://web.archive.org/web/20150411042510/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an -hulpnummers-tabel.html


Dat artikel is door mij geschreven in 2004. Dus wie de opmerking aan de functie heeft toegevoegd, graag gedaan. :-)


  1. Is het mogelijk om naar kolomnamen te verwijzen via bindvariabelen in Oracle?

  2. Python:best practice en veiligste manier om verbinding te maken met MySQL en query's uit te voeren

  3. Welk gegevenstype voor breedte- en lengtegraad?

  4. MySQL FLOOR() Functie – Naar beneden afronden op het dichtstbijzijnde gehele getal