Yes, that is correct.  Then compile with the preprocessor symbol 
SQLITE_WIN32_FILE_RANDOM defined.

generate_series is an extension module located in ext/misc/series.c

https://www.sqlite.org/src/dir?ci=567e09ef2a8cd84a&name=ext/misc

By default I load almost every one of those extensions in every sqlite3.dll and 
sqlite3.exe I compile (along with the INIT hook to get them loaded on each 
connection automatically -- basically make them all builtin extensions), along 
with a bunch of others I wrote myself that do things like add the entire 
standard math library, running statistics, a bunch of Windows functions (get 
the computer name, username, sids, translate sids between blobs and strings, 
check the token for sids, handle uuid functions etc), ip address functions, 
unicode case/accent folding, etc.  It makes the DLL and static shell about 2 
MB, but I have no shortage of CPU or memory anywhere ... (though I have to keep 
remembering whenever I move stuff to other servers and VMs that use actual slow 
hard drives that I have to keep the I/O rate within the piddly bounds of 
spinning rust -- NVMe and SSD drives with GB/s rather than KB/s IO rates can 
kill you).

I presume you are running current Win10Pro.  

There was a "bug" introduced in Defender back in late November that has now 
supposedly been fixed (don't know if it was in Defender or in Windows itself, 
but turning off the real-time defender fixed the issue) that adversely affected 
a bunch of crap (the main thing I noticed is that is doubled or more my build 
times -- by introducing the generic "doing nothing" (ie, some build processes 
loaded up all the SMT threads on the processor, and ran at 100% CPU usage for 
each thread on each core for a couple of minutes -- that time doubled and the 
CPU usage dropped to about 50% average on each thread) for which Microsoft is 
famous).  That has since been fixed (in March or something) and I haven't 
noticed anything else acting "weird" -- though like I said I have no idea if it 
was Defender that was the problem or if that just brought out some other issue 
in the windows kernel itself.

---
The fact that there's a Highway to Hell but only a Stairway to Heaven says a 
lot about anticipated traffic volume.


>-----Original Message-----
>From: sqlite-users [mailto:sqlite-users-
>boun...@mailinglists.sqlite.org] On Behalf Of x
>Sent: Friday, 15 June, 2018 02:06
>To: SQLite mailing list
>Subject: Re: [sqlite] .timer
>
>Keith, I can find no instance of 2966 in my sqlite.c code. I have
>found the code you mentioned
>
>
>
>  if( isDelete ){
>
>#if SQLITE_OS_WINCE
>
>        dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
>
>        isTemp = 1;
>
>#else
>
>        dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
>
>                                                          |
>FILE_ATTRIBUTE_HIDDEN
>
>                                                          |
>FILE_FLAG_DELETE_ON_CLOSE;
>
>#endif
>
>  }else{
>
>        dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
>
>  }
>
>
>
>Immediately after that section of code I’ve replaced
>
>
>
>#if SQLITE_OS_WINCE
>
>  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
>
>#endif
>
>
>
>With
>
>
>
> /* Reports from the internet are that performance is always
>
>  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
>
>#if SQLITE_OS_WINCE || SQLITE_WIN32_FILE_RANDOM
>
>  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
>
>#elif SQLITE_WIN32_FILE_SEQUENTIAL
>
>  dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
>
>#elif SQLITE_WIN32_FILE_WRITETHROUGH
>
>  dwFlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
>
>#elif SQLITE_WIN32_FILE_NOBUFFER
>
>  dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING;
>
>#endif
>
>
>
>Is that correct?
>
>
>
>BTW ‘select * from generate_series(1,10)’ gives me an error ‘no such
>table : generate_series’ in sqlite3.exe. I thought it was compiled
>into the shell by default?
>
>
>
>
>
>
>
>________________________________
>From: sqlite-users <sqlite-users-boun...@mailinglists.sqlite.org> on
>behalf of Keith Medcalf <kmedc...@dessus.com>
>Sent: Friday, June 15, 2018 8:10:19 AM
>To: SQLite mailing list
>Subject: Re: [sqlite] .timer
>
>
>Yes.  Search your sqlite3.c for #2966 (there is only one instance and
>it is in the winOpen function, somewhere around line 44847).  The
>code that is there will be an #ifdef that forces RANDOM_ACCESS only
>for WINCE.  Just change it so that you can compile it with
>RANDOM_ACCESS set and see if that makes a difference.  And yes, it
>will work in both 32 and 64 bit on Windows ... It will at least make
>the Windows caching deterministic (technically LRU).
>
>I know that Windows supposedly has some builtin rules about how it
>sets the default cache mode, but you should really have the whole
>file in the cache after each command since that is the purpose of the
>cache (memory not used is money wasted).
>
>Then re-run your test without freeing up physical cache memory
>between the runs (so the database stays in the cache).  The first run
>though the file will take a long time (SYS I/O Time) but subsequent
>passes should be very fast since the data is all already in the cache
>... (the USER time should stay about the same, but the SYS time will
>change depending on whether the file is in the cache or not).
>
>---
>The fact that there's a Highway to Hell but only a Stairway to Heaven
>says a lot about anticipated traffic volume.
>
>>-----Original Message-----
>>From: sqlite-users [mailto:sqlite-users-
>>boun...@mailinglists.sqlite.org] On Behalf Of x
>>Sent: Friday, 15 June, 2018 00:50
>>To: SQLite mailing list
>>Subject: Re: [sqlite] .timer
>>
>>Thanks for all the replies and great suggestions. I’m just up but
>>will shortly investigate all.
>>
>>
>>
>>After reading this post by Clemens Ladisch
>>
>>
>>
>>http://sqlite.1065341.n5.nabble.com/This-is-driving-me-nuts-
>>tp102034p102105.html
>>
>>
>>
>>I was guessing the answer might be something along the lines of what
>>is suggested below although I was clueless about how to go about it.
>>To be honest I’m still not sure Keith.
>>
>>
>>
>>1 Is #2699 an sqlite ticket? I can’t find it.
>>
>>2 Do I add this code to my sqlite3.c file? If so, whereabouts?
>>
>>3 Will it still work if I compile in 64 bit mode?
>>
>>
>>
>>________________________________
>>From: sqlite-users <sqlite-users-boun...@mailinglists.sqlite.org> on
>>behalf of Keith Medcalf <kmedc...@dessus.com>
>>Sent: Thursday, June 14, 2018 10:09:50 PM
>>To: SQLite mailing list
>>Subject: Re: [sqlite] .timer
>>
>>
>>See the following web page for how the default "Microsoft Magical
>>Mystery Cache Mode" works on Windows.  The term "Intelligent Read-
>>Ahead" applies only if you are 12 years old (typical Microsoft
>>behaviour).
>>
>>http://flylib.com/books/en/4.491.1.101/1/
>>
>>Note that the default mode is completely fracking useless for most
>>intents and purposes, and for databases the SEQUENTIAL mode is
>bloody
>>awful as well.
>>
>>However, the SEQUENTIAL mode seems to match what is being seen (the
>>look ahead is only working in one direction and pages are being
>>unmapped from the system cache at the wrong (read most stoopid) time
>>possible).
>>
>>So, the changes I made are to function winOpen as follows (after the
>>ticket #2699 comment).  Effectively I always set the flags for
>RANDOM
>>mode even though I am not Winders Crappy Edition ...
>>
>>  if( isDelete ){
>>#if SQLITE_OS_WINCE
>>    dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
>>    isTemp = 1;
>>#else
>>    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
>>                               | FILE_ATTRIBUTE_HIDDEN
>>                               | FILE_FLAG_DELETE_ON_CLOSE;
>>#endif
>>  }else{
>>    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
>>  }
>>  /* Reports from the internet are that performance is always
>>  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
>>#if SQLITE_OS_WINCE || SQLITE_WIN32_FILE_RANDOM
>>  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
>>#elif SQLITE_WIN32_FILE_SEQUENTIAL
>>  dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
>>#elif SQLITE_WIN32_FILE_WRITETHROUGH
>>  dwFlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
>>#elif SQLITE_WIN32_FILE_NOBUFFER
>>  dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING;
>>#endif
>>
>>This adds the SQLITE_WIN32_FILE_ ... defines and applies them in
>>order to all files opened by the Windows VFS.  I define
>>SQLITE_WIN32_FILE_RANDOM to make sure that the cache mode is always
>>set for RANDOM access and that read-ahead and idiot-mode (ie,
>>Microsoft-style) cache pruning are disabled, thus making the
>>FileSystem cache act in a deterministic LRU page ejecting fashion.
>>
>>---
>>The fact that there's a Highway to Hell but only a Stairway to
>Heaven
>>says a lot about anticipated traffic volume.
>>
>>
>>>-----Original Message-----
>>>From: sqlite-users [mailto:sqlite-users-
>>>boun...@mailinglists.sqlite.org] On Behalf Of Keith Medcalf
>>>Sent: Thursday, 14 June, 2018 14:16
>>>To: SQLite mailing list
>>>Subject: Re: [sqlite] .timer
>>>
>>>
>>>Cannot reproduce.
>>>
>>>I am using the current trunk that I compile myself with MinGW 8.1.0
>>>on Windows 10 1803 Pro for Workstations.  The laptop has a 4 Ghz
>>Quad
>>>Core Xeon and the disk is a Samsung NVMe drive.  About the only
>>>relevant change is that I have forced the Windows caching mode from
>>>"magical mystery Microsoft mode" to always use "Random access
>mode".
>>>It is also using the Win32 heap allocator.  I also have 32 GB of
>RAM
>>>and no third or fourth level page indirection or Virtual Arena
>>>diddling (that is, swapping is turned off).  I also have SQLite set
>>>to a 4K pagesize and have set 262144 pages of cache in SQLite by
>>>default.
>>>
>>>I forgot how slow CTE's are until I did this ... almost 3 times
>>>slower than using generate_series
>>>
>>>In RAM only -- Windows caching modes and disk I/O are irrelevant:
>>>
>>>>sqlite
>>>SQLite version 3.25.0 2018-06-13 17:19:20
>>>Enter ".help" for usage hints.
>>>Connected to a transient in-memory database.
>>>Use ".open FILENAME" to reopen on a persistent database.
>>>sqlite> create table test as -- creates test table with 100 million
>>>rows
>>>   ...> with recursive cte(x,y) as
>>>   ...> (values(1,'012345678901234567890123456789')
>>>   ...>  union all select x+1,y from cte where x<100000000)
>>>   ...> select * from cte;
>>>Run Time: real 34.619 user 34.625000 sys 0.000000
>>>sqlite> drop table test;
>>>Run Time: real 1.578 user 1.578125 sys 0.000000
>>>sqlite> create table test (x integer, y text);
>>>Run Time: real 0.000 user 0.000000 sys 0.000000
>>>sqlite> insert into test select value,
>>>'012345678901234567890123456789' from generate_series where start=1
>>>and stop=100000000;
>>>Run Time: real 12.226 user 12.234375 sys 0.000000
>>>sqlite> create temp table tasc1 as select rowid from test order by
>>>rowid asc;
>>>Run Time: real 11.408 user 11.140625 sys 0.265625
>>>sqlite> create temp table tdesc1 as select rowid from test order by
>>>rowid desc;
>>>Run Time: real 10.251 user 9.875000 sys 0.375000
>>>sqlite> create temp table tdesc2 as select rowid from test order by
>>>rowid desc;
>>>Run Time: real 10.188 user 9.828125 sys 0.359375
>>>sqlite> create temp table tasc2 as select rowid from test order by
>>>rowid asc;
>>>Run Time: real 11.563 user 11.218750 sys 0.328125
>>>sqlite> ^Z
>>>
>>>Timings are all pretty constant ... now with the db on disk ...
>>>
>>>>sqlite junk.db
>>>SQLite version 3.25.0 2018-06-13 17:19:20
>>>Enter ".help" for usage hints.
>>>sqlite> create table test (x integer, y text);
>>>Run Time: real 0.015 user 0.000000 sys 0.000000
>>>sqlite> insert into test select value,
>>>'012345678901234567890123456789' from generate_series where start=1
>>>and stop=100000000;
>>>Run Time: real 21.206 user 13.234375 sys 6.562500
>>>sqlite> create temp table tasc1 as select rowid from test order by
>>>rowid asc;
>>>Run Time: real 13.658 user 10.000000 sys 3.656250
>>>sqlite> create temp table tdesc1 as select rowid from test order by
>>>rowid desc;
>>>Run Time: real 12.658 user 9.500000 sys 3.156250
>>>sqlite> create temp table tasc2 as select rowid from test order by
>>>rowid asc;
>>>Run Time: real 13.017 user 10.031250 sys 2.984375
>>>sqlite> create temp table tdesc2 as select rowid from test order by
>>>rowid desc;
>>>Run Time: real 13.001 user 9.750000 sys 3.250000
>>>sqlite> .exit
>>>
>>>
>>>2018-06-14 13:47:30 PY2 [D:\]
>>>>dir junk.db
>>>2018-06-14  13:44     4,450,889,728 junk.db
>>>               1 File(s)  4,450,889,728 bytes
>>>               0 Dir(s)  330,480,447,488 bytes free
>>>
>>>So we have some difference in SYS time for I/O, but that is about
>>it.
>>>Still constant times.
>>>
>>>---
>>>The fact that there's a Highway to Hell but only a Stairway to
>>Heaven
>>>says a lot about anticipated traffic volume.
>>>
>>>
>>>>-----Original Message-----
>>>>From: sqlite-users [mailto:sqlite-users-
>>>>boun...@mailinglists.sqlite.org] On Behalf Of x
>>>>Sent: Thursday, 14 June, 2018 12:31
>>>>To: SQLite mailing list
>>>>Subject: Re: [sqlite] .timer
>>>>
>>>>Thanks for the replies. It is Windows Defender I’m using on a ms
>>>>surface pro 4 with 16 GB ram and 512 GB SSD. OS is Windows 10 Pro.
>>>>I’ve come up with the following demo using the sqlite shell. In it
>>I
>>>>use a couple of small apps called AvlRAM and FlushMem. Apart from
>>>>minor background tasks sqlite3.exe is the only app running.
>>>>
>>>>I downloaded FlushMem from here https://chadaustin.me/flushmem/
>and
>>>>changed it slightly so that it reported the available RAM before
>>and
>>>>after the flush. I was primarily interested in how sqlite was
>>>>performing after restarting the computer before any info was lying
>>>>about in caches as I was encountering some strange timings with
>>>such.
>>>>FlushMem saved me from continually rebooting and yielded results
>>>>similar to the ones I was experiencing with rebooting.
>>>>
>>>>The code for AvlRAM is as follows
>>>>
>>>>double FreeGBs()
>>>>{
>>>>        MEMORYSTATUSEX status;
>>>>        status.dwLength = sizeof(status);
>>>>        GlobalMemoryStatusEx(&status);
>>>>        return status.ullAvailPhys / (1024.0 * 1024 * 1024);
>>>>}
>>>>
>>>>int _tmain(int argc, _TCHAR* argv[])
>>>>{
>>>>        std::cout << FreeGBs() << " GBs" << std::endl;
>>>>        return 0;
>>>>}
>>>>
>>>>
>>>>Here’s the demo interspersed with comments
>>>>
>>>>SQLite version 3.24.0 2018-06-04 19:24:41
>>>>Enter ".help" for usage hints.
>>>>Connected to a transient in-memory database.
>>>>Use ".open FILENAME" to reopen on a persistent database.
>>>>sqlite> .timer on
>>>>sqlite> .open MyTemp.db -- open empty DB
>>>>sqlite> .shell FlushMem
>>>>Available RAM - pre flush = 12.913 GBs - post flush = 14.1749 GBs
>>>>
>>>>sqlite> create table test as -- creates test table with 100
>million
>>>>rows
>>>>   ...> with recursive cte(x,y) as
>>>>   ...> (values(1,'012345678901234567890123456789')
>>>>   ...> union all select x+1,y from cte where x<100000000)
>>>>   ...> select * from cte;
>>>>Run Time: real 77.239 user 68.750000 sys 7.468750
>>>>sqlite> .shell AvlRAM
>>>>14.1059 GBs
>>>>
>>>>sqlite> create temp table tasc as select RowID from test order by
>>>>RowID;
>>>>Run Time: real 32.473 user 25.203125 sys 7.203125
>>>>sqlite> .shell AvlRAM
>>>>14.1084 GBs
>>>>// little change to RAM, respectable time
>>>>
>>>>sqlite> create temp table tdesc as select RowID from test order by
>>>>RowID desc;
>>>>Run Time: real 32.056 user 24.515625 sys 7.531250
>>>>sqlite> .shell FlushMem
>>>>Available RAM - pre flush = 9.96339 GBs - post flush = 14.7108 GBs
>>>>// why does the RAM drop 4+ GB due to executing the above?,
>>>>respectable time
>>>>
>>>>
>>>>sqlite> create temp table tasc2 as select RowID from test order by
>>>>RowID;
>>>>Run Time: real 38.285 user 26.109375 sys 9.000000
>>>>sqlite> .shell FlushMem
>>>>Available RAM - pre flush = 14.5936 GBs - post flush = 14.7553 GBs
>>>>// no change to RAM, time a bit more sluggish after ‘reboot’ but
>>>>still respectable
>>>>
>>>>sqlite> create temp table tdesc2 as select RowID from test order
>by
>>>>RowID desc;
>>>>Run Time: real 117.765 user 28.265625 sys 13.828125
>>>>sqlite> .shell FlushMem
>>>>Available RAM - pre flush = 10.5519 GBs - post flush = 14.6888 GBs
>>>>// RAM drops 4+ GB, time is woeful. Why?
>>>>
>>>>// repeat above 2 ‘create temp table’ commands to demonstrate not
>>>>fluke
>>>>
>>>>sqlite> create temp table tasc3 as select RowID from test order by
>>>>RowID;
>>>>Run Time: real 41.747 user 26.562500 sys 10.625000
>>>>sqlite> .shell FlushMem
>>>>Available RAM - pre flush = 14.78 GBs - post flush = 14.754 GBs
>>>>// no change to RAM, time a bit more sluggish after ‘reboot’ but
>>>>still respectable
>>>>
>>>>sqlite> create temp table tdesc3 as select RowID from test order
>by
>>>>RowID desc;
>>>>Run Time: real 118.282 user 29.406250 sys 13.765625
>>>>sqlite> .shell FlushMem
>>>>Available RAM - pre flush = 10.6947 GBs - post flush = 14.5856 GBs
>>>>// RAM drops 4- GB, time is woeful. Why?
>>>>
>>>>sqlite> .exit
>>>>
>>>>
>>>>
>>>>Why is using ‘RowID desc’ so much slower than ‘RowID asc’ after a
>>>>‘reboot’? I get the impression Windows is caching the pages from
>>the
>>>>‘desc’ but not the ‘asc’ and that’s what’s slowing it down. On
>this
>>>>particular journey I’ve come across tables where the reverse was
>>the
>>>>case (I.e. it was the ‘asc’ that was woefully slow).
>>>>
>>>>Anyone cast any light on this?
>>>>_______________________________________________
>>>>sqlite-users mailing list
>>>>sqlite-users@mailinglists.sqlite.org
>>>>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-
>>users
>>>
>>>
>>>
>>>_______________________________________________
>>>sqlite-users mailing list
>>>sqlite-users@mailinglists.sqlite.org
>>>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-
>users
>>
>>
>>
>>_______________________________________________
>>sqlite-users mailing list
>>sqlite-users@mailinglists.sqlite.org
>>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>>_______________________________________________
>>sqlite-users mailing list
>>sqlite-users@mailinglists.sqlite.org
>>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
>
>
>_______________________________________________
>sqlite-users mailing list
>sqlite-users@mailinglists.sqlite.org
>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>_______________________________________________
>sqlite-users mailing list
>sqlite-users@mailinglists.sqlite.org
>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to