SQL - varchar a wydajność

0

Cześć,

dostaliśmy od pewnej firmy skrypty instalacyjne z procedurami, w których są zadeklarowane o wiele za duże zmienne. Przykład:

CREATE PROCEDURE [dbo].[EpuZazaleniaWyslij]
	@xmlPaczka [xml],
	@p_epuLogin [nvarchar](4000),
	@p_epuHaslo [nvarchar](4000),
	@p_epuApiKey [nvarchar](4000)

Czy coś takiego ma wpływ na szybkość działania?

2

Dlaczego uważasz, że sa za duże ? Tak naprawdę to zależy jak to baza itp. Np niektóre bazy i tak deklarują maksymalną długość varchara niezależnie od deklaracji.

0
Tomek Pycia napisał(a):

Dlaczego uważasz, że sa za duże?

Login mający kilka tysięcy znaków? Hasło to samo? W innej procedurze jest też przekazana data jako nvarchar(4000).
Co do bazy - sql server.

Po prostu wydaje mi się to bardzo nieeleganckie rozwiązanie i chciałbym wiedzieć czy oprócz względów estetycznych ma to jeszcze jakieś znaczenie?

6

Nie wiem, o jakiej bazie piszesz, nie wiem także, jak sytuacja wygląda w przypadku wszystkich RDBM'ów, ale np. w Postgresie nie ma to większego znaczenia (odpowiadając na pytanie Czy coś takiego ma wpływ na szybkość działania). Zobacz https://www.postgresql.org/docs/9.3/datatype-character.html - jest tam taki ciekawy fragment:

There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While character(n) has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact character(n) is usually the slowest of the three because of its additional storage costs. In most situations text or character varying should be used instead.

Dawniej używało się stałego rozmiaru żeby poprawić wydajność, było to wykonywane kosztem miejsca. Konkretnie to miejsca albo brakowało (jeśli długość varchar'a była za niska), albo się marnowało, jeśli dane były krótsze od rozmiaru przewidzianego na nie pola (puste miejsce było dobijane zerami). Teksty z dynamiczną długością zajmowały mniej miejsca w bazie, ale ich obsługa była bardziej problematyczna. Teraz, jak widać chociażby w podanym powyżej linku, różnic w wydajności praktycznie nie ma, więc definiowanie długości pól wydaje się bezsensowne, chyba, że są jakieś inne czynniki, np. wynikające z logiki biznesowej, które to uzasadniają i o których nie wspomniałeś. Mamy za mało informacji, więc ciężko powiedzieć, czy ktoś tak zrobił bo miał powód, czy tak zrobił bo koledzy tak robią i na pewno tak trzeba ;) Ale co do wydajności - nie masz co się obawiać, ustalenie długości nie ma wpływu na prędkość działania, a jak już to może lekko ją poprawić.

W innej procedurze jest też przekazana data jako nvarchar(4000).

No to lekki absurd i to z dwóch powodów. Po pierwsze - do trzymania dat w SQL są specjalne typu chociażby timestamp, ale nawet jakby ktoś miał ochotę trzymać to jako string, to kilkanaście znaków (zgodnie z formatem 03-07-2018) by było wystarczające. Podejrzewam, że albo ta dawana wszędzie długość 4000 jest jakimś hackiem dającym jakiś zysk na konkretnej bazie, albo (wersja bardziej prawdopodobna) ktoś ma średnie pojęcie lub ma dużą olewkę i po prostu wszędzie wali varchar(4000) ;)

2

Wygląda że żadnego (https://www.c-sharpcorner.com/UploadFile/a20beb/understanding-the-memory-consumption-of-char-varchar-nchar/)

nvarchar: nvarchar (national variable character) is used for storing the non-Unicode string values when the length of your values vary, in other words you don't know the length that the values will be. It consumes the memory on the basis of the passed value length not on the declared length. Unicode data consumes 2 times the space that non-Unicode data does.

2

Podajesz przykład zmiennych, które nie maja wpływu na to jak te dane będą przechowywane, wiec nie bardzo widzę jaki ma mieć to związek z szybkością...

Możemy dyskutować nad sensem takiego definiowania (nadmiarowego), ale nie o szybkości.

2

Wygląda na to że autorzy softu nie pokusili się o zdefiniowanie typów danych, a któraś z warstw po drodze przekonwertowała to na odgórnie ustalony limit 4000 znaków (MS SQL).
Źle świadczy to o autorach softu, ale jak napisano wyżej nie powinno mieć wpływu na wydajność, ew. na wykonywalność niektórych operacji (bazujących na rozmiarze rekordu).

Ciekawostka z msdn:

Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation, which counts against the 8,060-byte row limit during a sort operation. These additional bytes can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns in a table. No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8,060 bytes) or at the time of data insertion. This large row size can cause errors (such as error 512) that users may not anticipate during some normal operations. Two examples of operations are a clustered index key update, or sorts of the full column set.

https://docs.microsoft.com/en-us/sql/t-sql/data-types/nchar-and-nvarchar-transact-sql?view=sql-server-ver15

1 użytkowników online, w tym zalogowanych: 0, gości: 1