Ahoj všichni
Dnes mě požádali, abych při tisku implementačního dokumentu nezobrazoval předponu dokumentu, problém byl vyřešen následovně.

PageReplace (Number, Leo (Number, 3), "");

Když jsem se podíval na asistenta syntaxe, líbilo se mi to natolik, že jsem o něm chtěl psát práce s řetězci v 1C: Enterprise.

Řetězec v 1C odkazuje na primitivní datový typ.

Pokud se podíváte na nápovědu 1C, uvidíme následující popis typu String
Hodnoty tohoto typu obsahují řetězec Unicode libovolné délky.
Pokud podle vašich slov o řetězcích to bude fungovat. Řetězec je konstanta skládající se z různých znaků, vždy obklopená uvozovkami.

Nastavení řetězce
Call \u003d "Hello Passenger";

Víceřádkové řetězce v typických konfiguracích se nejčastěji vytvářejí pomocí svislého oddělovače „|“:
String \u003d "Víceřádkový
| řetězec
| napsat
| text ";

Uvozovky uvnitř řetězce jsou určeny dvojitými uvozovkami.
String \u003d "" Text v uvozovkách "";

Existuje mnoho operací s řetězci (hledání uvnitř řetězce, určení prvního atd.), Je lepší podívat se na Pomocníka syntaxe.
Syntax Assistant - Obecný popis vestavěného jazyka-\u003e vestavěné funkce-\u003e funkce pro práci s řetězci.

Řetězcové funkce

Tady v krátké formě dám funkce pro práci s řetězci:

BReg (<Строка>) - Funkce převede všechny znaky v řetězci na velká písmena.

SymbolCode (<Строка>, <НомерСимвола>) - Funkce obdrží kód znaku umístěného v předaném řetězci na pozici se zadaným číslem.

Lev(<Строка>, <ЧислоСимволов>) - Funkce vybere první znaky zleva od řetězce.

Najít(<Строка>, <ПодстрокаПоиска>) - Funkce vyhledá výskyt hledaného řetězce jako podřetězce v původním řetězci.

HPreg (<Строка>) - Funkce převede všechny znaky v řetězci na malá písmena.

Že jo (<Строка>, <ЧислоСимволов>) - Tato funkce se liší od levých funkcí tím, že vybírá poslední znaky řetězce vpravo.

Prázdný řádek (<Строка>) - Funkce kontroluje, zda řetězec obsahuje významné znaky.

Symbol(<КодСимвола>) - Funkce převede kód znaku na řetězec obsahující znak.

AbbrL (<Строка>) - Funkce ořízne bezvýznamné znaky nalevo od prvního významného znaku v řetězci.

SocrLP (<Строка>) - Funkce odstraní nevýznamné znaky nalevo od prvního významného znaku v řetězci a mezery napravo od posledního významného znaku v řetězci.

Zkratka (<Строка>) - Funkce ořízne bezvýznamné znaky napravo od posledního významného znaku v řetězci.

Středa (<Строка>, <НачальныйНомер>, <ЧислоСимволов>) - Funkce vybere řetězec znaků začínající znakem<НачальныйНомер>, dohromady<ЧислоСимволов>.

StrLength (<Строка>) - Funkce získá počet znaků v řetězci.

Nahradit (<Строка>, <ПодстрокаПоиска>, <ПодстрокаЗамены>) - Funkce najde všechny výskyty vyhledávacího podřetězce v původním řetězci a nahradí jej nahrazujícím podřetězcem.

StrGetString (<Строка>, <НомерСтроки>) - Funkce získá řetězec víceřádkového řetězce podle čísla.

Str Počet událostí (<Строка>, <ПодстрокаПоиска>) - Funkce vypočítá počet výskytů vyhledávacího podřetězce v původním řetězci.

RowNumber (<Строка>) - Funkce počítá počet řádků ve víceřádkovém řetězci. Ve víceřádkovém řetězci jsou řádky odděleny znaky posuvu řádku.

Treg (<Строка>) - Funkce převede řetězec na velká a malá písmena. To znamená, že u každého slova je první znak převeden na velká písmena nebo velká písmena, pokud pro znak není definován žádný velký název. Zbytek znaků se převede na malá písmena.

Zadejte převody
Pro explicitní převod datových typů existují funkce se stejným názvem s datovým typem, na který k převodu dochází: String (<Значение>)

StringOfNumbers \u003d Řetězec (číslo);

Všechny tyto funkce jsou podrobně popsány v Syntax Assistant, jak Syntax Assistant může pomoci začínajícímu programátorovi, jsem popsal v článku.

Příklady práce s řetězci

Převeďte číslo na řetězec a zpět.

Chcete-li získat řetězcovou reprezentaci roku, použijte funkci Format.

Year \u003d Format (CurrentDate (), "DF \u003d yyyy") // Year \u003d "2012"

Chcete-li převést číslo na řetězec bez vložení znaku oddělovače skupin (neporušený prostor), musíte použít funkci Formát s parametrem ChG \u003d 0:

Number \u003d 2012 String \u003d Format (Number, "CHG \u003d 0"); // String \u003d "2012"

Řetězec Žádné mezery.

Existuje několik mechanismů pro práci s řetězci v dotazech 1C. Nejprve lze přidat řádky. Za druhé, můžete si vzít podřetězec z řetězce. Za třetí, řetězce lze porovnávat, včetně vzorů. To je pravděpodobně vše, co můžete s řetězci dělat.

Zřetězení řetězců

K přidání řetězců do dotazu se používá operace „+“. Lze přidat pouze řádky omezené délky.

VYBERTE "Název:" + Protistrany. Název AS Sloupec 1 Z Adresáře. Dodavatelé AS Protistrany WHERE Protistrany. Odkaz \u003d & Odkaz

Funkce podřetězce

PODKLAD (<Строка>, <НачальнаяПозиция>, <Длина>)

Analogická funkce prostředí () z objektového modelu. Funkci Substring () lze použít na data typu řetězce a umožňuje vybrat fragment <Строки> počínaje číslem znaku <НачальнаяПозиция> (znaky v řetězci jsou očíslovány od 1) a délka <Длина> postavy. Výsledek vyhodnocení funkce má typ řetězce s proměnnou délkou a délka bude považována za neomezenou, pokud <Строка> má neomezenou délku a parametr <Длина> není konstantní nebo přesahuje 1024.

Pokud je délka řetězce menší než zadaná ve druhém parametru, vrátí funkce prázdný řetězec.

Pozornost! Použití funkce SUBSTRING () k převodu řetězců neomezené délky na řetězce omezené délky se nedoporučuje. Místo toho je lepší použít operaci obsazení EXPRESS ().

Funkce jako

Pokud se potřebujeme ujistit, že atribut řetězce splňuje určitá kritéria, porovnáme jej:

VYBRAT protistrany. Název AS Sloupec 1 Z adresáře. Protistrany AS Protistrany WHERE Protistrany. Název \u003d "Gazprom"

Ale co když chcete složitější srovnání? Nejen rovnost nebo nerovnost, ale jako určitý vzor? To je přesně to, pro co je vytvořena funkce LIKE.

LIKE - Operátor pro kontrolu řetězce jako vzoru. Analog LIKE v SQL.

Operátor LIKE umožňuje porovnat hodnotu zadaného výrazu nalevo od něj s řetězcem šablony určeným vpravo. Hodnota výrazu musí být typu string. Pokud hodnota výrazu odpovídá vzoru, vrátí operátor hodnotu TRUE, jinak bude FALSE.

Následující znaky v řetězci šablony jsou servisní znaky a mají jiný význam než znak řetězce:

  • % (procenta): sekvence obsahující libovolný počet libovolných znaků;
  • _ (podtržítko): jeden libovolný znak;
  • […] (Jeden nebo více znaků v hranatých závorkách): jakýkoli jeden znak uvedený v hranatých závorkách. Výčet může obsahovat rozsahy, například a-z, což znamená libovolný znak zahrnutý v rozsahu, včetně konců rozsahu;
  • [^…] (V hranatých závorkách znak negace následovaný jedním nebo více znaky): libovolný jeden znak, kromě těch, které jsou uvedeny za znakem negace.

Jakýkoli jiný symbol znamená sám sebe a nenese žádný další význam. Pokud jeden z uvedených znaků musí být zaznamenán jako sám, musí před ním být<Спецсимвол>... Sám<Спецсимвол> (jakýkoli vhodný znak) je definován ve stejném příkazu za klíčovým slovem SPECIÁLNÍ CHARAKTER.

Domácí poznámky z pohledu zrcadla

2. 7. 2013 Hledání podle řetězce

Implementováno ve verzi 8.3.3.641.

Udělali jsme zásadní vylepšení vstupu linky. K tomu jsme museli do vstupního pole implementovat nový výkonný vyhledávací mechanismus. Nyní může rychle pracovat s miliony záznamů obsažených v databázi.

Analyzovali jsme vyhledávací úlohy, se kterými se uživatelé setkali. Provedli jsme „audit“ mechanismů dostupných na platformě, které používají různé vyhledávací algoritmy. Výsledkem bylo, že vstup po řádku získal kvalitativně nové možnosti.

Uživatelé nyní mohou vyhledávat kdekoli v názvu, nejen na začátku řádku. Mohou používat fulltextové vyhledávání a dokonce i vyhledávání pomocí úlohy na pozadí. Aby fulltextové vyhledávání při zadávání řetězce fungovalo efektivně, dále jsme tento vyhledávač optimalizovali a zvýšili jeho výkon.

Všechny nové vlastnosti, které vám umožňují přizpůsobit vstup po řádku, jsme shromáždili na samostatné kartě okna pro úpravy konfiguračního objektu:

Můžete například určit, že hledání bude provedeno kdekoli v řetězci, nejen na začátku:

Uživatel pak může zadat libovolné fragmenty slov, nejen ty znaky, kterými začíná hledaný řetězec:

Použití fulltextového vyhledávání při zadávání řetězce umožňuje samostatná vlastnost:

Pomocí fulltextového vyhledávání mohou uživatelé rychle najít vhodná data mezi velkým množstvím dat pro některá ze slov obsažených, například v názvu:

Mohou také vyhledávat podle několika známých slov. Nedokončená slova budou automaticky doplněna možnými kombinacemi:

Pokud je objem dat velký, pak v obou případech můžete určit, že by vyhledávání mělo být prováděno pomocí úlohy na pozadí:

Poté se uživatelům vedle vstupního pole zobrazí animovaný obrázek podobný obrázku, který se zobrazí při spuštění sestavy na pozadí:

  • pokud se v objektu použitém ve vstupním poli neočekává velké množství dat, doporučujeme vám povolit hledání řetězce kdekoli;
  • pokud je v objektu plánováno velké množství dat, pak:
    • doporučujeme povolit fulltextové a pozadí vyhledávání;
    • v tomto případě můžete také použít hledání řetězce kdekoli, ale ve spojení s vyhledáváním na pozadí a nejlépe s fulltextovým vyhledáváním; takže většina vyhledávání se provádí pomocí fulltextového vyhledávání.

Pokud je to nutné, můžete během provádění aplikovaného řešení přepsat všechny uvedené vlastnosti.

Na klientovi - v obslužném programu události klienta zadávacího pole Automatický výběr a Vstup EndText :

Na serveru - v modulu správce objektu, v jehož datech se vyhledávání provádí. V obslužné rutině události ProcessingDataGettingChoice :

Přirozeně na tomto místě na serveru nemůžete přepsat způsob, jakým je vyhledávání prováděno. "Přímo" nebo „Práce na pozadí“ ... Protože spuštění kódu již bylo přeneseno na server.

Řetězec je jedním z primitivních datových typů v systémech 1C: Enterprise 8. Proměnné s typem čára obsahovat text.

Hodnoty typových proměnných čárajsou uvedeny v uvozovkách. Lze přidat několik proměnných tohoto typu.

Per1 \u003d "Slovo 1";
Per2 \u003d "Slovo 2";
Per3 \u003d Per1 + "" + Per2;

Nakonec Per3 bude znamenat „ Slovo 1 Slovo 2 “.

Systémy 1C: Enterprise 8 navíc poskytují funkce pro práci s řetězci. Zvažme ty hlavní:

Zavést řetězec (<Строка>, <Подсказка>, <Длина>, <Многострочность>) — funkce je navržena tak, aby zobrazovala dialogové okno, ve kterém může uživatel určit hodnotu proměnné typu Čára... Parametr <Строка> je povinné a obsahuje název proměnné, do které bude zapsán zadaný řetězec. Parametr <Подсказка> volitelný je název dialogového okna. Parametr <Длина> volitelný, označuje maximální délku vstupního řetězce. Výchozí hodnota je nula, což znamená neomezenou délku. Parametr <Многострочность> volitelný. Určuje režim zadávání víceřádkového textu: True - zadání víceřádkového textu s oddělovači řádků; False - jednoduché zadání řetězce.

Řetězec lze zadat a zadat kód znaků Unicode:

Symbol(<КодСимвола>) — kód se zadává jako číslo.

Písmeno \u003d Symbol (1103); // já

K dispozici je také inverzní funkce, která vám umožní zjistit kód znaku.

SymbolCode (<Строка>, <НомерСимвола>) — vrací číslo Unicode zadaného znaku jako číslo.

Funkce převodu případů:

BReg (<Строка>) - převede všechny znaky v řetězci na velká písmena.

HPreg (<Строка>) - převede všechny znaky v řetězci na malá písmena.

Treg (<Строка>) - převede všechny znaky v řetězci na velká písmena. To znamená, že první písmena všech slov jsou převedena na velká písmena a zbývající písmena jsou převedena na malá písmena.

Funkce pro vyhledávání a nahrazování znaků v řetězci:

Najít(<Строка>, <ПодстрокаПоиска>) - najde číslo znaku výskytu hledaného podřetězce. Například:

Najít ("Řetězec", "Dobře"); // 4

Vyhledávání (<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>) - najde číslo znaku výskytu vyhledávacího podřetězce, číslo výskytu je uvedeno v příslušném parametru. V tomto případě hledání začíná znakem, jehož číslo je uvedeno v parametru Počáteční pozice.Hledání je možné od začátku nebo od konce řetězce. Například:

Number4 Occurrences \u003d StrFind ( „Schopnost obrany“, „o“, směr vyhledávání. Od začátku, 1, 4); // 7

Nahradit (<Строка>, <ПодстрокаПоиска>, <ПодстрокаЗамены>) - najde všechny výskyty vyhledávacího podřetězce v původním řetězci a nahradí jej náhradním podřetězcem.

StrReplace ("String", "Oka", ""); // Stránka

Prázdný řádek (<Строка>) - zkontroluje řetězec, zda neobsahuje významné znaky. Pokud neexistují žádné významné znaky nebo vůbec žádné znaky, vrátí se hodnota Skutečný... V opačném případě - Ležící.

Str Počet událostí (<Строка>, <ПодстрокаПоиска>) - vypočítá počet výskytů vyhledávacího podřetězce v původním řetězci.

Str Počet událostí ( „Studuj, studuj a studuj znovu“, "studie", ""); // 3

PageTemplate (<Строка>, <ЗначениеПодстановки1>…<ЗначениеПодстановкиN> — nahradí parametry do řetězce číslem. Řádek musí obsahovat substituční značky ve tvaru: "% 1 ..% N". Značky jsou očíslovány od 1. Pokud je hodnota parametru Nedefinováno, je nahrazen prázdný řetězec.

PageTemplate ( „Parametr 1 \u003d% 1, parametr 2 \u003d% 2“, "1" , "2" ) ; // Parametr 1 \u003d 1, Parametr 2 \u003d 2

Funkce převodu řetězce:

Lev(<Строка>, <ЧислоСимволов>) - nejprve vrátí první znaky řetězce.

Že jo (<Строка>, <ЧислоСимволов>) - vrátí poslední znaky řetězce.

Středa (<Строка>, <НачальныйНомер>, <ЧислоСимволов>) - vrací řetězec délky<ЧислоСимволов>počínaje postavou<НачальныйНомер>.

AbbrL (<Строка>) zkrátí nevýznamné znaky nalevo od prvního významného znaku v řetězci.

Zkratka (<Строка>) - vyřízne nevýznamné znaky napravo od posledního významného znaku v řetězci.

SocrLP (<Строка>) - ořízne bezvýznamné znaky nalevo od prvního významného znaku v řádku a napravo od posledního významného znaku v řádku.

StrGetString (<Строка>, <НомерСтроки>) - získá víceřádkový řetězec podle čísla.

Další funkce:

StrLength (<Строка>) - vrací počet znaků v řetězci.

RowNumber (<Строка>) - vrací počet řádků ve víceřádkovém řetězci. Řádek je považován za nový, pokud je od předchozího řádku oddělen znakem posuvu řádku.

Porovnat (<Строка1>, <Строка2> ) - porovnává dva řetězce, nerozlišují se malá a velká písmena. Funkce funguje stejně jako objekt Srovnání hodnot... Vrací:

  • 1 - pokud je první řádek větší než druhý
  • -1 - pokud je druhý řádek větší než první
  • 0 - pokud jsou řetězce stejné

StrCompare ("První řádek", "Druhý řádek"); // jeden

Jmenuji se Pavel Barketov, pracuji pro Softpoint. Problémy s optimalizací výkonu řešíme již více než 10 let. A navzdory velkému počtu řešených problémů jejich počet neklesá, ale exponenciálně roste. Objemy dat se zvyšují a úkoly optimalizace práce s těmito daty se stávají obtížnějšími. Tento proces je nevyhnutelný.

Téma článku - netriviální přístupy k optimalizaci... Bude zváženo dva aspekty:

  • První - vyhledávání podřetězců... Uživatelé jej často používají a mnoho z nich již pravděpodobně čelilo významnému očekávání, že vyhledávání dílčích řetězců není dostatečně rychlé.
  • Druhý - držení velkých dokumentů, jako je uzavření měsíce, výpočet nákladů. Mnozí se jistě setkali se skutečností, že účetní tráví tyto dokumenty po dobu 5–9 hodin, v noci a mimo pracovní dobu. Nejzajímavější je, že klasické metody optimalizace zde ne vždy pomáhají. Pokud provádíte měření výkonu v debuggeru při provádění takových dokumentů, uvidíte, že největší čas strávíte zápisem do dočasných nebo skutečných struktur - tabulek, registrů atd. A je nemožné tento problém vyřešit klasickými metodami.

Hledání podle podřetězce

Prvním tématem je vyhledávání dílčích řetězců. Během tohoto roku jsem narazil na několik problémů s touto operací. Přicházíte do pojišťovny, abyste pojistku obnovili, nabízejí, že vás najdou podle telefonního čísla. Je jasné, že se nejedná o klasické hledání celého telefonního čísla, protože uživatel by mohl zadat číslo přes osm, přes sedm nebo něco jiného, \u200b\u200bproto hledá fragmenty čísla. V tomto případě se používají operace dlouhodobého vyhledávání - v řadě situací může být zpoždění několik sekund a může dokonce dosáhnout minut.

Hledání podle počátečních znaků

Začnu prvním příkladem, když se vyhledávání provádí na počátečních postavách. Jedná se o speciální případ hledání podřetězce, když uživatel ví jistě, že hledaná hodnota začíná určitými znaky.

Hledání podle počátečních znaků je implementováno v 1C pomocí příkazu LIKE (nebo v angličtině LIKE) s hodnotou s „%“ na konci („%“ označuje posloupnost dalších znaků). Například hledáme:

Název LIKE „ivano%“

Vezměte prosím na vědomí, že pokud máte index v tomto poli ve vašem systému, pak dotaz SQL použije pro toto hledání funkci Index Seek je indexové vyhledávání.

Podmínka „LIKE hledaný řetězec“ je ekvivalentní hledání v rozsahu hodnot... Ve zvláštním případě, když hledáme „ivano%“ - je to ekvivalentní hledání v řadě příjmení, která začínají na „ivano“ a končí na „ivanp“ (protože znak „p“ následuje za znakem „o“ ).

Moderní optimalizátory nezávisle převádějí LIKE dotaz na vyhledávací dotaz rozsahu... Pokud tedy máte ve svém systému index v tomto poli, získáte přesně stejný výsledek při interpretaci dotazu v podmínkách SQL - optimalizátor zobrazí dotaz s LIKE jako vyhledávání rozsahu.

Je tedy možné provést klasické rychlé vyhledávání pomocí indexového hledání. S tím nejsou žádné problémy, nebo je můžete vyřešit jednoduchým způsobem.

Hledat podle záznamu

Nyní si vezmeme složitější příklad, když není přesně známo, kde je v řetězci požadovaná hodnota, a hledání se provede výskytem řetězce. V tomto případě stojí v dotazu „LIKE“ „%“ na obou stranách.

Při převodu takového dotazu na SQL vidíme, že se mění pouze příkaz (hodnota již používá dvě „%“).

Pojďme se blíže podívat na plán provádění. Tady vidíme stejné hledání indexu, ale v tomto případě to nefunguje efektivně.

Faktem je, že index podle názvu referenční knihy, o kterém uvažujeme, se skládá z několika polí.

  • První je oddělovač účetnictví.
  • Další přímo je vyhledávací pole.

A proto, když se v plánu provádění zobrazí „Index Seek“, znamená to vyhledávání se provádí v prvním poli oddělovače - na snímku výše to vidíte vyhledávání na naší požadované hodnotě Desc se absolutně nepoužívá.

Co dělat v této situaci? V mé praxi bylo velmi často zakázáno uživatelům používat žádosti o vstup. A v některých případech samotní uživatelé tuto funkci nepoužívali, protože doba provádění je velmi významná, ale musí pokračovat v práci. Proto se museli dostat jiným způsobem - vybrali si v seznamech, pokusili se najít první znaky atd.

To však vede k nespokojenosti s funkčností a nesprávným vnímáním systému. Uživatel chápe, že systém se s něčím nedokáže vyrovnat a nefunguje podle očekávání. Není to správné.

Netriviální přístup k řešení problému vyhledávání podřetězců

Pojďme se nyní zamyslet netriviální přístup k řešení tohoto problému.

Pojďme určit řadu tolerancí:

  • První je proto moderní disky jsou neomezené, řekněme, že máte na disku spoustu místa, které můžete použít.
  • Druhý - uživatel nehledá podle jednoho nebo dvou znaků, ale podle nějakého fragmentu... Například nikdo z nás nehledá výraz „al“ - to je příliš malá selektivita. Hledáte nějaký smysluplný sled znaků. Zde jsme jako příklad vybrali vyhledávání podle šesti znaků.

Příklad požadovaného řetězce „alexa“ byl zapsán do formuláře a bude s ním testován.

  • Předpokládejme, že máme pole s příjmením, křestním jménem a příjmením klienta. Prvním krokem je automatické rozložení této hodnoty na fragmenty šesti znaků s posunem „1“a dostaneme řadu fragmentů (viz výše), které současně vždy patří k požadované hodnotě. Máme úryvky, které může uživatel teoreticky zadat. Konkrétně na posledním snímku bylo zjištěno, že hledáme šest znaků. Může jich být pět nebo čtyři, jen bude větší velikost konstrukce.

  • Ve druhém kroku jsme zapíšeme tyto sady do samostatné struktury (může to být tabulka, informační registr atd.) a dostaneme výběr, ve kterém určitý fragment patří k různým hodnotám.

  • A ve třetím kroku při hledání pomocí podřetězce přidáme další podmínku AND do konstrukce dotazu 1C "LIKE", která filtruje počet možných kombinací, a vytáhneme z této dodatečné struktury (může to být registr informací) všechny prvky, ke kterým patří nezbytné fragmenty, řádky.

Uživatel například hledá zákazníka s příjmením „Vojáci“. Toto je osm znaků, což znamená, že budou existovat tři fragmenty o délce šesti znaků, které hledáme ve struktuře služby. Dále to vše kombinujeme v požadavku. Tím se získá další filtrování.

Ve výsledku se zbavíme znaménka „%“ (to znamená, že tyto fragmenty budou mít vždy před sebou znak, který potřebujeme) a při provádění interního dotazu přejde Hledání indexu, za které jsme bojovali.

V praxi se ukáže velmi zajímavý příběh - zrychlení desítky, stokrát... To vše lze navíc provést pomocí 1C, což je velmi pěkné. Není třeba přepisovat logiku, uživatel bude rád, že jeho vyhledávací dotaz je rychlejší. V příkladu zrychlení ze 4 sekund na 0,05 sekundy a pokud bychom zpočátku měli požadavek spuštěný na dvě minuty, začal by se provádět za méně než sekundu.

Mechanismus, který jsem vám ukázal, není nějaký experimentální příklad, funguje již se skutečnými zákazníky.

Přípravné činnosti k provádění

Nyní krátce promluvím o přípravných činnostech.

  • Nejprve je nutné vyplnit registr počátečními hodnotami... K tomu musíme naplánovat naplánované okno.
  • Dále musíme dodržovat konzistenci dat - to znamená pro změnu hodnoty musí existovat předplatnétakže se tyto fragmenty automaticky přestaví.
  • A poslední - přidat standardní vyhledávací formulář.

Vyplňování registrů lze provádět jak pomocí 1C, tak pomocí SQL.

Mohu říci, že vyplnění takové struktury pro 17 milionů hodnot trvá asi 20-25 minut. Přirozeně by uživatelé v tuto chvíli neměli měnit hodnoty vyhledávání.

Pokud spočítáme pro jeden milion hodnot někde kolem 100 znaků o 6 ve fragmentu, dostaneme někde 4,7 GB. Musíte si naplánovat, abyste měli toto místo. Pokud máte v adresáři například 100 milionů hodnot, musíte naplánovat místo, které bude na disku k dispozici.

Nutnost zohlednit statistiky popularity fragmentů

Bude tato metoda vždy fungovat rychle?

To je ovlivněno statistiky popularity fragmentů.

  • Například máte fragment „alexe“, který lze zahrnout do jména Aleksey, do prostředního jména Alekseevich, do příjmení Alekseenko atd. Tento fragment lze zahrnout do 50–100 tisíc záznamů.
  • A tam jsou zřídka použité fragmenty.

Objevují se tedy statistiky popularity podle fragmentů.

Všimněte si, že pokud je popularita fragmentů nízká (100 prvků), dostaneme zrychlení 0,1 sekundy.

Pokud je podřetězec dostatečně populární (50 tisíc prvků), dojde k degradaci, a mnohem více, než kdyby neexistovala optimalizace.

Takto, musíte vytvořit vylepšené schéma provádění dotazůve kterém bychom nejprve získali popularitu poddotazu. To se děje ve třech až pěti řádcích v 1C. Zároveň víme jistě, že pokud je linka nepopulární, následuje první větev, a pokud je populární, pak druhou.

Jak funguje zrychlení? Z formuláře je požadavek na vyhledávání, pak se obrátíme na registr informací se statistikami, získáme prvek a poté vybereme, co použít - klasický nebo zrychlený požadavek.

Pojďme se nyní podívat na to, jak se SQL dotaz provádí na serveru SQL.

Na snímku je znázorněno zjednodušené schéma:

  • existuje požadavek na optimalizátor;
  • podíváme se na statistiky polí, která jsou použita v požadavku;
  • zvolíme, který plán provádění použít, tj. zvolíme strategii provádění dotazu (například vnořenou smyčku).

Jak vypadá obvod, který jsme implementovali?

  • Vyrobili jsme naše index... Ne standardní index SQL, ne index 1C, ale váš vlastní index, který je potřebný k vyřešení tohoto problému;
  • Navíc se potýkají s tím, že potřebují vlastní statistika;
  • A ty potřebuješ svůj vlastní optimalizátor, která pomocí těchto statistik rozhoduje, kterou větev zvolit.

Na základě této logiky můžeme říci, že tento proces odhaluje význam toho, co potřebujeme, indexy, statistiky a optimalizátor.

Kdo by nevěděl, proč potřebujete poskytovat statistiky v SQL, podívejte se na tuto logiku a pochopíte, že pokud je nesprávná nebo irelevantní, přejdeme do nesprávné větve. Požadavek se zpomalí. Chápeme, proč musíme poskytovat statistiky efektivně a správně - to ovlivňuje výkon, index.

Pokud neexistuje žádný index, prohledáme všechny hodnoty.

Vytvořili jsme tedy alespoň primitivní, ale náš vlastní optimalizátor. Dá se říci, že cítili „na prstech“, jak to MS SQL a další DBMS dělají, a vytvořili si vlastní struktury.

Urychlení "velkých" dokumentů

Přechod na druhé téma - zrychlení velkých dokumentů.

Ve výrobních úkolech se často setkáváme s nějakými rutinními postupy, jako je uzavření měsíce, hlášení agentovi, výpočet nákladové ceny. Dokončení a dokončení těchto těžkých a rozsáhlých dokumentů trvá značně dlouho. A když se podíváme do debuggeru a sledujeme tyto operace, vidíme to 1C vloží hodnoty řádek po řádku do nějaké tabulky a zabere to většinu času... A s tím se nedá nic dělat. Jediným doporučením, které lze nabídnout, je zrychlení disku (účinnost tohoto řešení je velmi sporná a vyžaduje předběžnou analýzu).

Navrhuji vrátit se do historie a zvážit, jak se to stalo v 1C, od 8,0 do 8,3 - to bylo provedeno řádek po řádku... Server SQL pokaždé analyzoval požadavek, zpracoval jej, vytvořil plán provádění, přidal jej, odeslal příkaz směrem k 1C o úspěchu a obdržel další požadavek. A takové krok za krokem byly zaslány požadavky z aplikačního serveru 1C na MS SQL.

Je jasné, že pokud máte v dokumentu 40 záznamů, nemělo by dojít k žádným problémům. Pokud máte 10 tisíc nebo více záznamů (existují organizace, kde je v regulačních dokumentech milion záznamů), pak tento proces trvá velmi dlouho. Jeden záznam je zpracován velmi rychle, ale v dokumentu je jich příliš mnoho. Jaké jsou režijní náklady? Do sítě, k provedení požadavku, ke zpětnému signálu, ke zpracování tohoto signálu v systému 1C - celkem, součet čtyř stupňů. Všechny fáze jsou sečteny, vynásobeny milionem řádků a dostáváme naše dlouhá očekávání. Je jasné, že to není hrozné.

V 1C, počínaje verzí 8.3, byla provedena vylepšení. Nyní je na serveru SQL připraven dotaz pro vložení do dočasných tabulek a informačních registrů a jeho další provádění probíhá pomocí klasických RPC volání, kde samotný poskytovatel přístupu 1C (nativní nebo OLE DB) seskupuje záznamy a vkládá je pomocí N řádků (obvykle 100 řádků).

Tím je dosaženo zrychlení o 30% až 300%. Ale to stále nestačí, protože dnes máte 10 tisíc řádků, zítra 20 tisíc řádků. Nejedná se o zásadní řešení problému, budete mu stále čelit, ale pouze za šest měsíců / rok.

Co nejrychlejší vložka na server SQL nebo na jakýkoli DBMS?

to HROMADNÁ VLOŽKA... V 1C se používá BULK INSERT, ale pro jiné úkoly. Také bych chtěl urychlit práci s „velkými“ dokumenty zvětšením INSERT vložek a přidáním záznamů v jednom poli do databáze serveru SQL.

Podívejme se, jakého účinku je dosaženo. V uvažovaném příkladu zrychlení je asi 5krát, ale můžete zrychlit 10krát... Teoreticky je hlavním problémem tohoto podstatně větší akcelerace rychlost disku. Disk může být překážkou.

Taky je důležité pamatovat na takové kritérium jako indexy... Pokud bychom měli vložit BULK INSERT do tabulky bez aktualizace indexů, pak bychom dostali významné zrychlení (výsledky za méně než sekundu). Tady dostaneme 69 sekund kvůli tomu, že každá příloha v tabulce vyžaduje index REFRESH.

V každém případě vám tato metoda umožňuje dosáhnout účinku 5-10krát.

Navíc zde nejsou brány v úvahu funkce jako rozdělení na oddíly, rozdělení. Situaci by bylo možné vylepšit, kdybychom věděli, že BULK INSERT je vložen v aktuálním období, a přesunuli bychom irelevantní jeden do jiného oddílu. Bylo by to ještě efektivnější. Ukazuje se, že zrychlení je velmi dobré.

Možnosti optimalizace jsou nekonečné

Takto, možnosti optimalizace jsou nekonečné... Jedinou věcí je nenechat se unést. Před optimalizací má vždy smysl vypočítat, zda zamýšlený efekt bude nebo nebude. Také bych doporučil v některých situacích „povznést se“ nad problém, nepoužívat klasické metody optimalizace dotazů, ale některé zcela odlišné, které mohou přinést významnější výsledky.

****************

Tento článek byl napsán na základě výsledků zprávy () přečtené na konferenci INFOSTART EVENT 2017 COMMUNITY.