Piszę w C# prosty program obsługujący bazę danych SQLite. Do połączenia wykorzystuję darmową bibliotekę System.Data.SQLite.dll.
Program działa tak, że jak się na wejściu poda pewien tekst, to program rozdziela go na poszczególne linie i uruchamia każdą linię osobno w pętli, ponieważ w odróżnieniu od MS SQL, SQLite nie umie przetworzyć serii poleceń za jednym zamachem.
Testowa seria:
create table TestTable (Brand varchar(100), BOX int, Begin varchar(100), End varchar(100))
insert into TestTable values ('ALFA',1,'0','210')
insert into TestTable values ('ALFA',2,'211','349')
insert into TestTable values ('ALFA',3,'350','460')
insert into TestTable values ('ALFA',4,'461','590')
insert into TestTable values ('ALFA',5,'591','715')
insert into TestTable values ('ALFA',6,'716','<')
insert into TestTable values ('AST',1,'0','<')
insert into TestTable values ('BENT',1,'0','<')
insert into TestTable values ('BLMC',1,'0','JQ')
insert into TestTable values ('BLMC',2,'JR','<')
insert into TestTable values ('BMW',1,'0','3')
insert into TestTable values ('BMW',2,'4','A49')
insert into TestTable values ('BMW',3,'A50','<')
insert into TestTable values ('CHRY',1,'0','G')
insert into TestTable values ('CHRY',2,'H','PR')
insert into TestTable values ('CHRY',3,'PS','<')
insert into TestTable values ('CITR',1,'0','EX')
insert into TestTable values ('CITR',2,'EY','KJ')
insert into TestTable values ('CITR',3,'KK','KP')
insert into TestTable values ('CITR',4,'KQ','<')
insert into TestTable values ('DAEW',1,'0','49')
insert into TestTable values ('DAEW',2,'50','<')
insert into TestTable values ('DAI',1,'0','G')
insert into TestTable values ('DAI',2,'H','<')
insert into TestTable values ('FAUS',1,'0','<')
insert into TestTable values ('FER',1,'0','<')
insert into TestTable values ('FIAT',1,'0','210')
insert into TestTable values ('FIAT',2,'211','349')
insert into TestTable values ('FIAT',3,'350','460')
insert into TestTable values ('FIAT',4,'461','590')
insert into TestTable values ('FIAT',5,'591','715')
insert into TestTable values ('FIAT',6,'716','<')
insert into TestTable values ('FORD',1,'0','590')
insert into TestTable values ('FORD',2,'591','680')
insert into TestTable values ('FORD',3,'681','<')
insert into TestTable values ('FUSA',1,'0','D')
insert into TestTable values ('FUSA',2,'E','J')
insert into TestTable values ('FUSA',3,'K','SN')
insert into TestTable values ('FUSA',4,'SO','<')
insert into TestTable values ('GM',1,'0','25')
insert into TestTable values ('GM',2,'26','44')
insert into TestTable values ('GM',3,'45','70')
insert into TestTable values ('GM',4,'71','89')
insert into TestTable values ('GM',5,'90','<')
insert into TestTable values ('GMH',1,'0','<')
insert into TestTable values ('HON',1,'0','BG4')
insert into TestTable values ('HON',2,'BG5','NH630')
insert into TestTable values ('HON',3,'NH631','R5')
insert into TestTable values ('HON',4,'R6','<')
insert into TestTable values ('HYU',1,'0','G')
insert into TestTable values ('HYU',2,'H','O')
insert into TestTable values ('HYU',3,'P','U')
insert into TestTable values ('HYU',4,'V','<')
insert into TestTable values ('ISU',1,'0','<')
insert into TestTable values ('JAG',1,'0','<')
insert into TestTable values ('KIA',1,'0','E')
insert into TestTable values ('KIA',2,'F','<')
insert into TestTable values ('LADA',1,'0','<')
insert into TestTable values ('LAM',1,'0','<')
insert into TestTable values ('LOT',1,'0','<')
insert into TestTable values ('LRR',1,'0','JQ')
insert into TestTable values ('LRR',2,'JR','<')
insert into TestTable values ('MAS',1,'0','<')
insert into TestTable values ('MAZ',1,'0','29')
insert into TestTable values ('MAZ',2,'30','<')
insert into TestTable values ('MER',1,'0','52')
insert into TestTable values ('MER',2,'53','<')
insert into TestTable values ('MINI',1,'0','3')
insert into TestTable values ('MINI',2,'4','A49')
insert into TestTable values ('MINI',3,'A50','<')
insert into TestTable values ('MIT',1,'0','E')
insert into TestTable values ('MIT',2,'F','S')
insert into TestTable values ('MIT',3,'T','<')
insert into TestTable values ('NIS',1,'0','BS')
insert into TestTable values ('NIS',2,'BT','D')
insert into TestTable values ('NIS',3,'E','KK')
insert into TestTable values ('NIS',4,'KL','<')
insert into TestTable values ('OPEL',1,'0','20')
insert into TestTable values ('OPEL',2,'21','369')
insert into TestTable values ('OPEL',3,'370','<')
insert into TestTable values ('PEU',1,'0','EX')
insert into TestTable values ('PEU',2,'EY','KJ')
insert into TestTable values ('PEU',3,'KK','KP')
insert into TestTable values ('PEU',4,'KQ','<')
insert into TestTable values ('POR',1,'0','<')
insert into TestTable values ('PROT',1,'0','<')
insert into TestTable values ('REN',1,'0','6')
insert into TestTable values ('REN',2,'7','D')
insert into TestTable values ('REN',3,'E','<')
insert into TestTable values ('RR',1,'0','<')
insert into TestTable values ('SAAB',1,'0','<')
insert into TestTable values ('SEAT',1,'0','<')
insert into TestTable values ('SKO',1,'0','<')
insert into TestTable values ('SMAR',1,'0','<')
insert into TestTable values ('SSA',1,'0','<')
insert into TestTable values ('SUB',1,'0','4')
insert into TestTable values ('SUB',2,'5','<')
insert into TestTable values ('SUZ',1,'0','Z6')
insert into TestTable values ('SUZ',2,'Z7','ZJ9')
insert into TestTable values ('SUZ',3,'ZJA','<')
insert into TestTable values ('TOY',1,'0','1D')
insert into TestTable values ('TOY',2,'1E','3N')
insert into TestTable values ('TOY',3,'3O','6L')
insert into TestTable values ('TOY',4,'6M','750')
insert into TestTable values ('TOY',5,'751','8P')
insert into TestTable values ('TOY',6,'8Q','<')
insert into TestTable values ('UC',1,'1','<')
insert into TestTable values ('VOL',1,'0','3')
insert into TestTable values ('VOL',2,'4','<')
insert into TestTable values ('VW',1,'0','C3')
insert into TestTable values ('VW',2,'C4','K')
insert into TestTable values ('VW',3,'L','Y3')
insert into TestTable values ('VW',4,'Y4','<')
insert into TestTable values ('WHEEL',1,'0','<')
Wykonanie serii w transakcji i poza transakcją w tym programie wygląda tak samo, jedyna różnica, to taka, że przed pętlą jest otwarcie transakcji, po pętli jej zamknięcie (commit lub rollback), a przy generowaniu polecenia, przd jego wykonaniem jest ono wiązane z daną transakcją. W takim razie różnica w szybkości wynika na pewno z pracy bazy danych a nie z mojego kodu (czas przetwarzania i wykonania od strony programu jest praktycznie taki sam w obu przypadkach).
W tym wszystkim zadziwiający jest fakt, że jak się wykona powyższą serię poza transakcją, to trwa to kilka sekund, a jak się wykona w transakcji, to wykonanie trwa ułamek sekundy. Sprawdzałem i w obu przypadkach tabela jest prawidłowo zbudowana i wypełniona danymi.
Tak na chłopski rozum, to wykonanie w transakcji powinno być wolniejsze niz poza transakcją, bo w transakcji system bazodanowy oprócz zapisu danych musi gdzieś zapisywać co i gdzie zmienić, żeby mógł wszystko odwrócić przy wykonaniu rollback, a tutaj jest dokładnie na odwrót. Dlaczego?