Søk etter den siste forekomsten av et tegn i streng 1s. Eksempler på arbeid med strenger

I denne artikkelen vil jeg fortelle deg om hurtigsøkfunksjonen 1C Enterprise 8. Hva er raskt søk? Veldig enkelt. Rask søk ​​er en av måtene å navigere i store lister med 1C-poster. Dette kan være lister over dokumenter, kataloger, registre - alt som er representert av tabeller.

Hva er raskt søk?

Hurtigsøkfunksjonen i 1C Enterprise-dokumenter er ekstremt praktisk og lar deg ikke bla gjennom store mengder data (for eksempel ved å bruke rullefelt), men å gå direkte til ønsket sted i listen. Dessverre bruker ikke nybegynnere av 1C Enterprise 8 (inkludert 1C Accounting 8) først raske søkemuligheter, og foretrekker å bla gjennom dokumentlistene manuelt (og de kan høyt stor). Denne artikkelen vil hjelpe deg med å finne ut hvordan du bruker raskt søk i 1C.

Først og fremst bør det bemerkes at i 1C Enterprise 8-konfigurasjoner, bygget på administrerte skjemaer, fungerer hurtigsøk annerledes enn i tidligere versjoner av 1C. Derfor vil vi analysere separat bruk av hurtigsøk i administrerte skjemaer og i vanlige skjemaer.

Rask søk ​​i 1C Regnskap 8.2

I versjoner av 1C Accounting fra 8.0 til 8.2 funksjonen er ment spesielt for overgang til ønsket del av listen. Se for eksempel på vinduet med kontoplaner vist i figuren.


En bestemt linje er uthevet i vinduet. Legg merke til den subtile trekanten av striper som er angitt med den røde pilen. Som i andre Windows-programmer der det er lister (for eksempel i Utforsker), bestemmer plasseringen til denne markøren (trekanten) sorteringen av listen som en helhet - i hvilken kolonne markøren er satt, vil hele listen sorteres etter den kolonnen. I figuren er markøren i kodekolonnen, derfor blir kontoene i kontoplanen sortert etter kode.

Markøren kan flyttes fra en kolonne til en annen ved å klikke på ønsket kolonne ( på HEADER av kolonnen!) med musen. Hvis markøren allerede er i den gjeldende kolonnen, endrer du sorteringsretningen til det motsatte ved å klikke (dvs. fra større til mindre eller omvendt). Dette er standard oppførsel for ethvert Windows-program. Hva er særegenheten til denne markøren i 1C Enterprise, og hvordan er den relatert til raskt søk?

Et raskt søk i 1C Enterprise 8-lister utføres av kolonnen der markøren er plassert. I dette tilfellet vil et raskt søk i kontoplanen bli utført av kolonnen Kode.

Det var en viktig del av artikkelen, men uten JavaScript er den ikke synlig!

Hvordan bruke hurtigsøk i 1C? Enkelt! Bare begynn å skrive det du vil finne i DENNE kolonnen, dvs. hvor markøren er. I eksemplet på bildet over må kontonummeret legges inn. For eksempel vil du finne konto 50 Cashier. I dette tilfellet skriver du inn ( du trenger ikke å klikke hvor som helst!) nummeret 50 fra tastaturet, og hvis det er en konto med dette nummeret i denne kolonnen (og selvfølgelig er det en), vil listen bla til denne linjen, og selve linjen vil bli uthevet. Resultatet vises på skjermbildet av kontoplanen nedenfor.

nettside_

Teksten som pilen peker på er ikke behov for å vaske- han vil selv forsvinne.

Hvis du i eksemplet ovenfor begynner å skrive ordet "Kassereren", blir teksten nederst i vinduet lagt inn og deretter slettet. Dette skjer fordi så snart Start den angitte hurtigsøkestrengen slutter å falle sammen med begynnelsen på minst en linje i denne kolonnen, 1C Enterprise konkluderer med at søkestrengen ikke ble funnet og sletter den automatisk. Angående det er to regler å huske.

I 1C Enterprise 8 utføres et raskt søk i begynnelsen av linjen, dvs. kolonnen søker etter et treff av den skrevne teksten med begynnelsen på en av linjene i denne kolonnen.
Dette fører til en viktig anbefaling: Når du legger inn data i kataloger, navngi elementene slik at det er praktisk å søke etter dem ved hjelp av et raskt søk. For eksempel er navnet på motparten bedre skrevet som "NameFirm LLC" enn "LLC NameFirmy". Videre bør du ikke bruke anførselstegn og andre unødvendige symboler i navnet (vi snakker om å fylle ut Navn-feltet i skjemaer).

Hvis du begynner å skrive, og den blir slettet, er det du leter etter ikke i denne kolonnen! I dette tilfellet, sjekk inndataspråket, samt kolonnen der hurtigsøket utføres. En vanlig feil er at feil kolonne er valgt. For eksempel settes markøren i kodekolonnen, og søket utføres av navnet på kontoen.

Raskt søk i 1C Regnskap 8.3

La oss nå se hvor raskt søket er forskjellig i 1C Enterprise 8.3. Bruk er veldig lik 8.2, men det er en betydelig forskjell å huske.

I 1C Accounting 8.3, så vel som i andre konfigurasjoner på administrerte skjemaer (det samme nye grensesnittet), fungerer det som et filter. Enkelt sagt, som et resultat av hurtigsøkfunksjonen, en del av listen skjule.

Hvordan du bruker det, vil vi finne ut nå. Se først på skjermbildet av vinduet 1C Accounting 8.3 med kontopanelet nedenfor.

nettside_

Som du kan se, er den samme markøren i en av kolonnene. Søket utføres også av kolonnen der markøren er satt. Alt dette forble uendret. Men hvis du begynner å skrive inn tekst (i eksemplet kontonummeret), vil følgende skje.

nettside_

Som du ser, åpnet søkeboksen nettopp automatisk. Det samme vinduet åpnes hvis du klikker på søkeknappen på verktøylinjen i vinduet (understreket i figuren). Som et resultat, når du klikker på Finn-knappen i søkevinduet (skjult bak rullegardinmenyen på bildet) eller bare Enter, får du følgende resultat.

nettside_

Fra dette er det klart at raskt søk i 1C Accounting 8.3 etterlater bare synlig del av listen som oppfyller søkebetingelsene. I dette tilfellet forsvinner Finn-knappen, og i stedet vises en linse med et kryss (understreket i figuren). Når du klikker på den, går listen tilbake til sin opprinnelige tilstand (linjen funnet som et resultat av et raskt søk forblir uthevet ).

En annen viktig funksjon ved raskt søk i 1C Accounting 8.3- det ikke søkes etter et treff i begynnelsen av en linje, som i versjon 8.2, men det blir søkt etter et treff med en hvilken som helst del av linjene i kolonnen. Dermed, hvis motparten kalles "NameFirm LLC", og når du søker begynner å angi "NameFirm LLC", vil linjen fremdeles bli funnet!

Trekke konklusjoner

Dermed er et raskt søk i 1C Accounting 8.2 og tidligere ment å bla listen til ønsket linje, og i 1C Accounting 8.3 fungerer et hurtigsøk som et vanlig filter, og skjuler den delen av listen du ikke trenger.

Det er få mekanismer for å jobbe med strenger i 1C-spørsmål. Først kan linjene legges til. For det andre kan du ta en substring fra en streng. For det tredje kan strengene sammenlignes, inkludert etter mønster. Det er sannsynligvis alt du kan gjøre med strenger.

Sammenkobling av strenger

For å legge til strenger i et spørsmål, brukes "+". Bare strenger av begrenset lengde kan legges til.

VELG "Navn:" + Motparter. Navn AS Kolonne1 FRA Katalog. Motparter AS Motparter HVOR Motparter. Link = & Link

Substring-funksjon

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

Analog av funksjonen Miljø () fra objektmodellen. Substring () -funksjonen kan brukes på data av en strengtype og lar deg velge et fragment <Строки> starter med tegnnummeret <НачальнаяПозиция> (tegn i strengen er nummerert fra 1) og lengde <Длина> tegn. Resultatet av å evaluere funksjonen har en strengtype med variabel lengde, og lengden vil bli ansett som ubegrenset hvis <Строка> har ubegrenset lengde og parameter <Длина> er ikke konstant eller overstiger 1024.

Hvis strenglengden er mindre enn spesifisert i den andre parameteren, vil funksjonen returnere en tom streng.

Merk følgende! Det anbefales ikke å bruke SUBSTRING () for å konvertere strenger med ubegrenset lengde til strenger med begrenset lengde. Det er bedre å bruke en rollebesetning som EXPRESS () i stedet.

Funksjon som

Hvis vi trenger å sørge for at et strengattributt oppfyller visse kriterier, sammenligner vi det:

VELG Motparter. Navn som kolonne1 FRA katalogen. Motparter som motparter HVOR motparter. Navn = "Gazprom"

Men hva om du vil ha en vanskeligere sammenligning? Ikke bare likhet eller ulikhet, men som et bestemt mønster? Dette er akkurat hva funksjonen LIKE ble opprettet for.

LIKE - Operatør for å sjekke en streng som et mønster. Analog av LIKE i SQL.

LIKE-operatøren lar deg sammenligne verdien av uttrykket som er angitt til venstre for det med malstrengen som er spesifisert til høyre. Uttrykkverdien må være av typen streng. Hvis uttrykksverdien samsvarer med mønsteret, vil operatøren resultere i SANT, ellers - FALSE.

Følgende tegn i malstrengen er servicetegn og har en annen betydning enn strengtegnet:

  • % (prosent): en sekvens som inneholder et hvilket som helst antall vilkårlige tegn;
  • _ (understrek): ett vilkårlig tegn;
  • […] (Ett eller flere tegn i parentes): ethvert enkelt tegn som er oppført i parentes. Oppregningen kan inneholde områder, for eksempel a-z, som betyr en vilkårlig karakter som er inkludert i området, inkludert endene av området;
  • [^…] (I firkantede parenteser et negasjonstegn etterfulgt av ett eller flere tegn): et enkelt tegn, unntatt de som er oppført etter negasjonstegnet.

Ethvert annet symbol betyr seg selv og har ingen ekstra betydning. Hvis det er nødvendig å skrive en av de oppførte tegnene som seg selv, må den være foran<Спецсимвол>... Han selv<Спецсимвол>(hvilket som helst passende tegn) er definert i samme uttalelse etter nøkkelordet SPESIALTEGN.

En streng er en av de primitive datatypene i 1C: Enterprise 8. -systemer. Variabler med typen linje inneholder tekst.

Verdier av typevariabler linje er omsluttet av doble anførselstegn. Flere variabler av denne typen kan legges til.

Per1 = "Ord 1";
Per2 = "Word 2";
Per3 = Per1 + "" + Per2;

Etter hvert Per3 vil bety “ Ord 1 Ord 2 ″.

I tillegg har 1C: Enterprise 8-systemer funksjoner for arbeid med strenger. La oss vurdere de viktigste:

Skriv inn streng (<Строка>, <Подсказка>, <Длина>, <Многострочность>) — funksjonen er ment å vise en dialogboks der brukeren kan spesifisere verdien på en variabel av typen Linje... Parameter <Строка> kreves og inneholder navnet på variabelen som den angitte strengen skal skrives til. Parameter <Подсказка> valgfritt er tittelen på dialogboksen. Parameter <Длина> valgfri, angir maksimal lengde på inngangsstrengen. Standard er null, noe som betyr ubegrenset lengde. Parameter <Многострочность> valgfri. Bestemmer inndatamodus for flerlinjetekst: Sann - inntasting av flerlinjetekst med linjeseparatorer; Falsk - input av en enkel streng.

Strengen kan legges inn og få Unicode-tegnkoden:

Symbol (<КодСимвола>) — koden legges inn som et nummer.

Bokstav = Symbol (1103); // JEG

Det er også en omvendt funksjon som lar deg finne ut koden til et tegn.

Symbolkode (<Строка>, <НомерСимвола>) — returnerer det angitte Unicode-tegnnummeret som et tall.

Funksjoner for sakskonvertering:

BReg (<Строка>) - konverterer alle tegn i strengen til store bokstaver.

HPreg (<Строка>) - konverterer alle tegn i strengen til små bokstaver.

Treg (<Строка>) - konverterer alle tegn i en streng til store bokstaver. Det vil si at de første bokstavene i alle ord blir konvertert til store bokstaver, og resten av bokstavene blir konvertert til små bokstaver.

Funksjoner for å søke og erstatte tegn i en streng:

Å finne(<Строка>, <ПодстрокаПоиска>) - finner tegnnummeret til forekomsten av søkestrengen. For eksempel:

Finn ("String", "Oka"); // fire

Finn (<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>) - finner tegnnummeret til forekomsten av søkesubstringen, forekomstnummeret er angitt i den tilsvarende parameteren. I dette tilfellet begynner søket med et tegn hvis nummer er spesifisert i parameteren Start posisjon. Søk er mulig fra begynnelsen eller fra slutten av strengen. For eksempel:

Number4 Forekomster = StrFind ( "Forsvarsevne", "o", Søk retning. Fra begynnelsen, 1, 4); // 7

PR stedet (<Строка>, <ПодстрокаПоиска>, <ПодстрокаЗамены>) - finner alle forekomster av søkesubstringen i den originale strengen og erstatter den med erstatningssubstringen.

StrReplace ("String", "Oka", ""); // Side

Tom linje (<Строка>) - sjekker strengen for signifikante tegn. Hvis det ikke er noen signifikante tegn eller ingen tegn i det hele tatt, returneres verdien ekte... Ellers - Falsk.

Antall forekomster (<Строка>, <ПодстрокаПоиска>) - beregner antall forekomster av søkesubstringen i den opprinnelige strengen.

Antall forekomster ( "Studer, studer og studer igjen", "å studere" , "" ) ; // 3

Sidemall (<Строка>, <ЗначениеПодстановки1>…<ЗначениеПодстановкиN> — erstatter parametere i strengen etter antall. Linjen må inneholde erstatningsmarkører av skjemaet: "% 1 ..% N". Markører nummereres fra 1. Hvis parameterverdien Udefinert, er en tom streng erstattet.

Sidemall ( "Parameter 1 =% 1, Parameter 2 =% 2", "1" , "2" ) ; // Parameter 1 = 1, Parameter 2 = 2

Stringkonvertering funksjoner:

En løve(<Строка>, <ЧислоСимволов>) - returnerer de første tegnene i strengen først.

Ikke sant (<Строка>, <ЧислоСимволов>) - returnerer de siste tegnene i strengen.

Onsdag (<Строка>, <НачальныйНомер>, <ЧислоСимволов>) - returnerer en streng med lengde<ЧислоСимволов>starter med karakteren<НачальныйНомер>.

AbbrL (<Строка>) avkorter ubetydelige tegn til venstre for det første betydningsfulle tegnet i strengen.

Forkortelse (<Строка>) - kutter av ubetydelige tegn til høyre for det siste betydningsfulle tegnet i strengen.

SocrLP (<Строка>) - kutter av ubetydelige tegn til venstre for det første betydningsfulle tegnet i linjen og til høyre for det siste betydningsfulle tegnet i linjen.

StrGetString (<Строка>, <НомерСтроки>) - får en streng av en flerlinjestreng etter nummer.

Andre funksjoner:

StrLength (<Строка>) - returnerer antall tegn i en streng.

StrNumber of Lines (<Строка>) - returnerer antall linjer i en streng med flere linjer. En linje regnes som ny hvis den er skilt fra den forrige linjen med en ny linje.

Sammenlign (<Строка1>, <Строка2> ) - sammenligner to strenger, små og store bokstaver. Funksjonen fungerer på samme måte som et objekt Sammenligning av verdier... Returnerer:

  • 1 - hvis den første linjen er større enn den andre
  • -1 - hvis den andre linjen er større enn den første
  • 0 - hvis strengene er like

Sammenlign ("Første linje", "Andre linje"); // en

Jeg heter Pavel Barketov, jeg jobber for Softpoint. Vi har løst ytelsesoptimaliseringsproblemer i over 10 år. Og til tross for det store antallet løste problemer, reduseres antallet ikke, men vokser eksponentielt. Datamengdene øker, og oppgavene med å optimalisere arbeidet med disse dataene blir vanskeligere. Denne prosessen er uunngåelig.

Emnet for artikkelen - ikke-trivielle tilnærminger til optimalisering... Vil bli vurdert to aspekter:

  • Først - substring søk... Brukere bruker det ofte, og mange har sannsynligvis allerede møtt en betydelig forventning om at undersøk av søk ikke er raske nok.
  • Sekund - holder store dokumenter, for eksempel å stenge måneden, beregne kostprisen. Sikkert mange har kommet over det faktum at regnskapsførere bruker disse dokumentene i 5-9 timer, om natten og etter timer. Det mest interessante er at klassiske optimaliseringsmetoder ikke alltid hjelper her. Hvis du kjører en ytelsesmåling i feilsøkingsprogrammet mens du utfører slike dokumenter, vil du se at mest tid brukes på å skrive til midlertidige eller virkelige strukturer - tabeller, registre osv. Og det er umulig å løse dette problemet med klassiske metoder.

Søk etter substring

Det første emnet er søk etter strenger. I løpet av dette året har jeg fått flere problemer med denne operasjonen. Du kommer til forsikringsselskapet for å fornye polisen, de tilbyr å finne deg på telefonnummer. Det er klart at dette ikke er et klassisk søk ​​etter hele telefonnummeret, fordi brukeren kan angi nummeret gjennom de åtte, gjennom de syv, eller noe annet, derfor leter de etter fragmenter av nummeret. I dette tilfellet brukes langvarige søkeoperasjoner - i noen situasjoner kan forsinkelsen være flere sekunder, eller det kan gå opp til minutter.

Søk ved å starte tegn

Jeg begynner med det første eksemplet når søket utføres ved å starte tegn. Dette er et spesielt tilfelle av et substringsøk, når brukeren vet helt sikkert at søkeverdien begynner med bestemte tegn.

Søk etter innledende tegn er implementert i 1C ved hjelp av kommandoen LIKE(eller på engelsk, LIKE) med en verdi med "%" på slutten ("%" betegner en sekvens av andre tegn). For eksempel ser vi etter:

Navn LIKE "ivano%"

Vær oppmerksom på at hvis du har en indeks på dette feltet i systemet ditt, da SQL-spørringen vil bruke Index Seek for dette søket er et indeks søk.

Betingelsen "LIKE search string" tilsvarer søking i et verdiområde... I det spesielle tilfellet, når vi søker etter "ivano%" - tilsvarer det å søke i en rekke etternavn som starter med "ivano" og slutter med "ivanp" (fordi "p" -tegnet kommer etter "o" -tegnet ).

Moderne optimaliserere konverterer uavhengig et LIKE-spørring til et søk... Derfor, hvis du har en indeks på dette feltet i systemet ditt, vil du få nøyaktig det samme resultatet når du tolker spørringen i SQL-termer - optimalisereren vil presentere spørringen med LIKE som et områdesøk.

Dermed er det mulig å utføre et klassisk raskt søk ved hjelp av indeksen (Index Seek). Det er ingen problemer med dette, eller du kan løse dem på en enkel måte.

Søk etter oppføring

La oss nå ta et mer komplisert eksempel når det ikke er kjent nøyaktig hvor i strengen vår ønskede verdi er, og et søk blir implementert av forekomsten av strengen. I dette tilfellet står "%" i spørringen "LIKE" på begge sider.

Når vi konverterer et slikt spørsmål til SQL, ser vi at bare kommandoen endres (verdien inneholder allerede to "%").

La oss se nærmere på gjennomføringsplanen. Her vi ser det samme Index Seek, men i dette tilfellet fungerer det ikke effektivt.

Faktum er at indeksen med navnet på referanseboken, som vi vurderer, består av flere felt.

  • Den første er regnskapsskilleren.
  • Neste direkte er søkefeltet.

Og derfor, når "Index Seek" vises i utførelsesplanen, betyr det at søket er gjort på det første feltet i skilletegn- på lysbildet over kan du se det å søke på ønsket Desc-verdi brukes absolutt ikke.

Hva skal jeg gjøre i denne situasjonen? I min praksis var det veldig ofte at brukerne ble forbudt å bruke inngangsforespørsler. Og i noen tilfeller brukte brukerne ikke denne funksjonaliteten, fordi utførelsestiden er veldig viktig, men de må fortsette å jobbe. Derfor måtte de komme seg ut på andre måter - de valgte i listene, prøvde å finne etter de første tegnene, og så videre.

Men dette fører til misnøye med funksjonaliteten og misoppfatningen av systemet. Brukeren forstår at systemet ikke takler noe og ikke fungerer som forventet. Det er ikke riktig.

En ikke-triviell tilnærming til å løse problemet med substring-søk

La oss nå vurdere ikke-triviell tilnærming til å løse dette problemet.

La oss angi en rekke toleranser:

  • Den første er fordi moderne diskene er ubegrensede La oss si at du har mye diskplass du kan bruke.
  • Sekund - brukeren søker ikke etter ett eller to tegn, men etter et fragment... For eksempel søker ingen av oss etter "al" - dette er for lite selektivitet. Leter du etter en meningsfull sekvens av tegn. Her har vi valgt å søke etter seks tegn som et eksempel.

Et eksempel på den nødvendige strengen "alexe" ble skrevet inn i skjemaet, og vi vil teste den med dens hjelp.

  • Anta at vi har et felt med etternavn, fornavn og patronym av en klient. Det første trinnet er å automatisk spalte denne verdien i fragmenter på seks tegn med et skift på "1" og vi får en rekke fragmenter (se ovenfor), som samtidig alltid hører til ønsket verdi. Vi fikk utdrag som brukeren teoretisk kan legge inn. På det siste lysbildet ble det nemlig bestemt at vi ser etter seks tegn. Det kan være fem eller fire av dem, bare størrelsen på strukturen vil være større.

  • I det andre trinnet, vi vi skriver disse settene i en egen struktur(dette kan være en tabell, informasjonsregister osv.) og vi får et utvalg der et bestemt fragment tilhører forskjellige verdier.

  • Og på det tredje trinnet, når vi søker etter et underlag, legger vi til en ekstra OG-tilstand til 1C-spørrekonstruksjonen "LIKE", som filtrerer antall mulige kombinasjoner, og trekker ut fra denne tilleggsstrukturen (det kan være et register over informasjon ) alle elementene som de nødvendige fragmentene tilhører linjer.

For eksempel leter en bruker etter en kunde med etternavnet "Soldiers". Dette er åtte tegn, noe som betyr at det vil være tre fragmenter på seks tegn, som vi ser etter i tjenestestrukturen. Deretter kombinerer vi alt dette i en forespørsel. Dermed oppnås ytterligere filtrering.

Som et resultat blir vi kvitt "%" -tegnet (det vil si at disse fragmentene alltid vil ha den karakteren vi trenger foran seg), og når du utfører et internt spørsmål, vil Index Seek gå, som vi kjempet for.

I praksis viser det seg en veldig interessant historie - akselerasjon med titalls, hundrevis av ganger... Videre kan alt dette gjøres ved hjelp av 1C, noe som er veldig hyggelig. Det er ikke nødvendig å omskrive logikken, brukeren vil være glad for at søket hans har akselerert. I eksemplet, akselerasjon fra 4 sekunder til 0,05 sekunder, og hvis vi i utgangspunktet hadde en henvendelse utført i to minutter, ville den begynne å utføres på mindre enn et sekund.

Mekanismen som jeg viste deg, er ikke noe slags eksperimentelt eksempel, den fungerer allerede med ekte kunder.

Forberedende aktiviteter for gjennomføring

Nå skal jeg snakke kort om de forberedende aktivitetene.

  • Først det er nødvendig å fylle registeret med startverdier... For dette må vi planlegge et planlagt vindu.
  • Deretter må vi observere konsistensen av dataene - dette betyr, det må være et abonnement for å endre verdien slik at disse fragmentene automatisk blir gjenoppbygd.
  • Og den siste - legg til et standard søkeskjema.

Registerfylling kan gjøres både ved hjelp av 1C og ved hjelp av SQL.

Jeg kan si at å fylle ut en slik struktur for 17 millioner verdier tar omtrent 20-25 minutter. Naturligvis bør brukerne for øyeblikket ikke endre verdiene for oppslaget.

Hvis vi beregner for en million verdier et sted rundt 100 tegn med 6 i et fragment, får vi et sted 4,7 GB. Du må planlegge slik at du har dette stedet. Hvis du for eksempel har 100 millioner verdier i katalogen, må du planlegge plassen som vil være tilgjengelig på disken.

Behovet for å ta hensyn til statistikken over fragmentenes popularitet

Vil denne metoden alltid fungere raskt?

Dette er påvirket av fragment popularitetsstatistikk.

  • For eksempel har du et fragment "alexe", som kan inngå i navnet Aleksey, i mellomnavnet Alekseevich, i etternavnet Alekseenko, etc. Dette fragmentet kan inngå i 50-100 tusen poster.
  • Og det er sjelden brukte fragmenter.

Dermed vises statistikken over popularitet etter fragmenter.

noter det hvis populariteten til fragmentene er lav (100 elementer), så får vi en akselerasjon på 0,1 sekund.

Hvis undergrunnen er populær nok (50 tusen elementer), får vi nedbrytning, og mye mer enn om det ikke var noen optimalisering.

På denne måten, det er nødvendig å lage en forbedret ordning for spørreutførelse der vi først skulle få verdien av populariteten til undersøket. Dette gjøres i tre til fem linjer i 1C. Samtidig vet vi med sikkerhet at hvis en linje er upopulær, følger den den første grenen, og hvis den er populær, følger den den andre.

Hvordan fungerer akselerasjon? Det er en søkeforespørsel fra skjemaet, så vender vi oss til registeret med informasjon med statistikk, får elementet og velger deretter hva vi skal bruke - en klassisk eller en akselerert forespørsel.

La oss nå se på hvordan SQL-spørringen kjøres på SQL-serveren.

Lysbildet viser et forenklet diagram:

  • det er en forespørsel til optimalisereren;
  • vi ser på statistikk over feltene som brukes i forespørselen;
  • vi velger hvilken utførelsesplan vi vil bruke, det vil si at vi velger en spørringsutførelsesstrategi (for eksempel en nestet løkke).

Hvordan ser kretsen vi har implementert ut?

  • Vi laget vår indeks... Ikke en standard SQL-indeks, ikke en 1C-indeks, men din egen indeks, som er nødvendig for å løse dette problemet;
  • Dessuten sto de overfor det faktum at de trengte sine egne statistikk;
  • Og du trenger din egen optimizer, som, basert på denne statistikken, bestemmer hvilken gren du vil velge.

Basert på denne logikken kan vi si at denne prosessen avslører betydningen av hva indekser, statistikk og en optimizer er til.

Hvem visste ikke hvorfor du trenger å levere statistikk i SQL, se på denne logikken, og du vil forstå at hvis den er feil eller irrelevant, så vil vi gå til feil gren. Forespørselen vil avta. Vi forstår hvorfor vi må levere statistikk effektivt og riktig - dette påvirker ytelsen og indeksen.

Hvis det ikke er noen indeks, vil vi skanne alle verdiene.

Dermed har vi laget i det minste en primitiv, men vår egen optimizer. Vi kan si at de følte "på fingrene" hvordan MS SQL og andre DBMS gjør det, og skapte sine egne strukturer.

Fremskynde "store" dokumenter

Gå videre til det andre emnet - øke hastigheten på store dokumenter.

I produksjonsoppgaver står vi ofte overfor en slags rutinemessige prosedyrer, som å avslutte måneden, rapportere til agenten, beregne kostnadene. Disse tunge, massive dokumentene tar lang tid å fullføre og fullføre. Og når vi ser på feilsøkingsprogrammet og sporer disse operasjonene på disse operasjonene, ser vi det 1C setter inn verdier linje for linje i noen tabeller, og det tar mesteparten av tiden... Og ingenting kan gjøres med det. Den eneste anbefalingen som kan tilbys er å øke hastigheten på disken (effektiviteten til denne løsningen er veldig tvilsom og krever foreløpig analyse).

Jeg foreslår å gå tilbake til historien og vurdere hvordan det ble gjort i 1C, fra 8,0 til 8,3 - dette ble gjort linje for linje... SQL-serveren analyserte forespørselen hver gang, behandlet den, opprettet en utførelsesplan, la den til, sendte en kommando mot 1C om suksess og mottok neste forespørsel. Og slike trinnvise forespørsler ble sendt fra 1C applikasjonsserveren til MS SQL.

Det er klart at hvis du har 40 poster i dokumentet, så burde det ikke være noen problemer. Hvis du har 10 tusen eller flere poster (det er organisasjoner der det er en million poster i reguleringsdokumenter), så tar denne prosessen veldig lang tid. Én post behandles veldig raskt, men det er for mange av dem i dokumentet. Hva er overheadkostnadene? Til nettverket, for å oppfylle en forespørsel, til et retursignal, for å behandle dette signalet i 1C-systemet - totalt summen av fire trinn. Alle trinn er oppsummert, multiplisert med en million linjer, og vi får våre lange forventninger. Det er klart at dette ikke er forferdelig.

I 1C, fra og med 8.3, er forbedringer gjort. Nå utarbeides et spørsmål for innsetting i midlertidige tabeller og informasjonsregistre på SQL-serveren, og den videre kjøringen skjer ved bruk av klassiske RPC-anrop, hvor selve 1C-tilgangsleverandøren (Native eller OLE DB) grupperer poster og setter dem inn etter N-linjer (vanligvis 100 linjer).

Dermed oppnås en akselerasjon på 30% til 300%. Men dette er fortsatt ikke nok, for i dag har du 10 tusen linjer, i morgen 20 tusen linjer. Dette er ikke en grunnleggende løsning på problemet, du vil fortsatt møte det, men bare etter seks måneder / et år.

Hva raskeste innsatsen til en SQL-server, og til enhver DBMS?

den BULKINSETT... I 1C brukes BULK INSERT, men til andre oppgaver. Jeg vil også fremskynde arbeidet med "store" dokumenter ved å konsolidere INSERT-innlegg og legge til poster i en enkelt matrise i SQL-serverdatabasen.

La oss se hvilken effekt som oppnås. I det vurderte eksemplet fikk vi akselerasjon er omtrent 5 ganger, men du kan akselerere 10 ganger... I teorien er det største problemet for at dette skal akselerere betydelig mer diskhastigheten. Disken kan være en flaskehals.

Også det er viktig å huske på et slikt kriterium som indekser... Hvis vi skulle sette inn en BULKINSERT i en tabell uten å oppdatere indeksene, ville vi få en betydelig hastighet (resulterer i mindre enn et sekund). Her får vi 69 sekunder på grunn av at hvert innlegg i tabellen krever en REFRESH-indeks.

I alle fall tillater denne metoden deg å oppnå en effekt på 5-10 ganger.

I tillegg vurderes ikke funksjoner som partisjonering, partisjonering her. Situasjonen kan forbedres hvis vi visste at BULK INSERT er satt inn i inneværende periode, og vi vil flytte den irrelevante til en annen partisjon. Det ville være enda mer effektivt. Det viser seg at akselerasjonen er veldig god.

Optimaliseringsmulighetene er uendelige

På denne måten, optimaliseringsmulighetene er uendelige... Det eneste er å ikke la seg rive med. Før optimalisering er det alltid fornuftig å beregne om den tiltenkte effekten blir eller ikke. I noen situasjoner vil jeg også råde til å "løfte meg" over problemet, ikke å bruke klassiske metoder for spørringsoptimalisering, men noen helt andre som kan gi mer signifikante resultater.

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

Denne artikkelen ble skrevet basert på resultatene av rapporten () som ble lest på INFOSTART EVENT 2017 COMMUNITY-konferansen.