Re: [sqlite] sqlite3 query really slow with version > 3.7.5

2011-10-16 Thread Dan Kennedy

On 10/17/2011 11:05 AM, Owen Kaluza wrote:

Hi,

After upgrading my OS I noticed a huge delay loading my application, I
narrowed it down to my system libsqlite3 being upgraded from 3.7.4 to 3.7.7
I did some quick testing with different versions and it seems the change
comes about between 3.7.5 and 3.7.6.2
The query difference is huge:

Open database successful, SQLite version 3.7.5
0.2800 seconds to load 16 geometry records from database

Open database successful, SQLite version 3.7.6.2
30.8400 seconds to load 16 geometry records from database

As you can see from the last row the same delay occurs even when no records
are found!
Queries to other tables in the db cause no problem, it's only the table that
holds the majority of the data (in blob fields), example query:

SELECT
timestep,rank,idx,type,data_type,size,count,width,minimum,maximum,dim_factor,units,labels,data
FROM geometry WHERE object_id=1 AND timestep=0  ORDER BY idx,rank;

Table schema:
CREATE TABLE geometry (id INTEGER PRIMARY KEY ASC, object_id INTEGER,
timestep INTEGER, rank INTEGER, idx INTEGER, type INTEGER, data_type
INTEGER, size INTEGER, count INTEGER, width INTEGER, minimum REAL, maximum
REAL, dim_factor REAL, units VARCHAR(32), labels VARCHAR(2048), properties
VARCHAR(2048), data BLOB, FOREIGN KEY (object_id) REFERENCES object (id) ON
DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (timestep) REFERENCES timestep
(id) ON DELETE CASCADE ON UPDATE CASCADE);



Likely you are hitting a problem causing SQLite to create an automatic
index for this type of query. Fixed here:

  http://www.sqlite.org/src/ci/27c65d4d9c?sbs=0

Updating to 3.7.8 should fix it.


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] sqlite3 query really slow with version > 3.7.5

2011-10-16 Thread Owen Kaluza
Hi,

After upgrading my OS I noticed a huge delay loading my application, I
narrowed it down to my system libsqlite3 being upgraded from 3.7.4 to 3.7.7
I did some quick testing with different versions and it seems the change
comes about between 3.7.5 and 3.7.6.2
The query difference is huge:

Open database successful, SQLite version 3.7.5
... loaded 8 rows, 11300352 bytes, 0.2000 seconds
... loaded 2 rows, 16 bytes, 0.0100 seconds
... loaded 2 rows, 3390352 bytes, 0.0500 seconds
... loaded 2 rows, 1131968 bytes, 0. seconds
... loaded 2 rows, 1126736 bytes, 0.0100 seconds
... loaded 0 rows, 0 bytes, 0. seconds
0.2800 seconds to load 16 geometry records from database

Open database successful, SQLite version 3.7.6.2
... loaded 8 rows, 11300352 bytes, 5.4300 seconds
... loaded 2 rows, 16 bytes, 5.2200 seconds
... loaded 2 rows, 3390352 bytes, 5.2100 seconds
... loaded 2 rows, 1131968 bytes, 5. seconds
... loaded 2 rows, 1126736 bytes, 4.9900 seconds
... loaded 0 rows, 0 bytes, 4.9800 seconds
30.8400 seconds to load 16 geometry records from database

As you can see from the last row the same delay occurs even when no records
are found!
Queries to other tables in the db cause no problem, it's only the table that
holds the majority of the data (in blob fields), example query:

SELECT
timestep,rank,idx,type,data_type,size,count,width,minimum,maximum,dim_factor,units,labels,data
FROM geometry WHERE object_id=1 AND timestep=0  ORDER BY idx,rank;

The delay occurs in the read loop on: sqlite3_step(statement);
Same delay if I issue this query in the sqlite3 shell (~ 5 seconds).

Table schema:
CREATE TABLE geometry (id INTEGER PRIMARY KEY ASC, object_id INTEGER,
timestep INTEGER, rank INTEGER, idx INTEGER, type INTEGER, data_type
INTEGER, size INTEGER, count INTEGER, width INTEGER, minimum REAL, maximum
REAL, dim_factor REAL, units VARCHAR(32), labels VARCHAR(2048), properties
VARCHAR(2048), data BLOB, FOREIGN KEY (object_id) REFERENCES object (id) ON
DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (timestep) REFERENCES timestep
(id) ON DELETE CASCADE ON UPDATE CASCADE);

Any ideas what has changed that could cause this and if there's a way I can
work around it?

Thanks in advance,
Owen.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] DOMAIN new error code

2011-10-16 Thread Roger Binns
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 16/10/11 17:21, Jean-Christophe Deschamps wrote:
> rather than being confronted to the uninformative SQLITE_ERROR "SQL
> error or missing database".

That is the default text for the error code, but your extension should
provide different text.

Adding a new error code won't really help that much.  For example what
happens if someone combines your math library with my Python extension as
you wouldn't be able to tell which is responsible for a SQLITE_DOMAIN.

Roger
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)

iEYEARECAAYFAk6bp94ACgkQmOOfHg372QRsSwCfbFOBZtNiS9/yLDFLSgNliV6D
AakAnjwXBV5MRvlbKv5MnOwzdCImXpmd
=NkfC
-END PGP SIGNATURE-
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Sqlite3_step

2011-10-16 Thread Sreekumar TP
Hi,

I do not have a ORDER BY , only  a WHERE  clause. So sorting should not be
the cause for the overhead.

-Sreekumar



On Mon, Oct 17, 2011 at 9:08 AM, Simon Slavin  wrote:

>
> On 17 Oct 2011, at 4:22am, Sreekumar TP wrote:
>
> > In case of a prepared statement that uses SELECT
> > , the first sqlite3_step statement consumes a lot of time (order of
> > magnitude can be 100 or more)
> > when compared to the subsequent executions of step used to iterate
> through
> > the results. Does the first execution of step cache the entire result set
> > and tje subsequent steps get the results from the cache?
>
> The first step has to make a lot of decisions about what plan to follow in
> retrieving the rows: Which index is the best to use ?  Is it going to be
> necessary to sort the rows even after that index ?  These things do take
> some extra time.
>
> If it turns out that one of the available indexes will produce the rows in
> exactly the order wanted, then it will not be necessary to store all the
> rows which should be returned.  SQLite just stores the query plan: it
> remembers how to find each next row, rather than remembering the data in
> those rows.
>
> On the other hand, if it is necessary for SQLite to sort the rows itself,
> because no good index has been created, then yes, it will have to sort the
> rows in order to figure out which one to return first, and having sorted
> them it will store them so that subsequent _step()s can just return the next
> row.
>
> Simon.
>  ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Sqlite3_step

2011-10-16 Thread Simon Slavin

On 17 Oct 2011, at 4:22am, Sreekumar TP wrote:

> In case of a prepared statement that uses SELECT
> , the first sqlite3_step statement consumes a lot of time (order of
> magnitude can be 100 or more)
> when compared to the subsequent executions of step used to iterate through
> the results. Does the first execution of step cache the entire result set
> and tje subsequent steps get the results from the cache?

The first step has to make a lot of decisions about what plan to follow in 
retrieving the rows: Which index is the best to use ?  Is it going to be 
necessary to sort the rows even after that index ?  These things do take some 
extra time.

If it turns out that one of the available indexes will produce the rows in 
exactly the order wanted, then it will not be necessary to store all the rows 
which should be returned.  SQLite just stores the query plan: it remembers how 
to find each next row, rather than remembering the data in those rows.

On the other hand, if it is necessary for SQLite to sort the rows itself, 
because no good index has been created, then yes, it will have to sort the rows 
in order to figure out which one to return first, and having sorted them it 
will store them so that subsequent _step()s can just return the next row.

Simon.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Sqlite3_step

2011-10-16 Thread Roger Binns
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 16/10/11 20:22, Sreekumar TP wrote:
> Does the first execution of step cache the entire result set and tje
> subsequent steps get the results from the cache?

No, the first execution does the minimum amount of work necessary in order
to get you the first result row.  Subsequent steps do only the work
necessary to get the next row.

However if your query needs the rows to be sorted then all of the result
rows will have to be found first in order to do the sorting.  (Some sorts
can be satisfied from an index.)

Roger
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)

iEYEARECAAYFAk6botAACgkQmOOfHg372QS+1gCeNPAie5rgEcUH+2gFJAT8iZVq
n5UAoMl0HkipR2qN5Vr9dLg+jc+3dYhT
=rHPf
-END PGP SIGNATURE-
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Sqlite3_step

2011-10-16 Thread Sreekumar TP
Hi,

In case of a prepared statement that uses SELECT
, the first sqlite3_step statement consumes a lot of time (order of
magnitude can be 100 or more)
when compared to the subsequent executions of step used to iterate through
the results. Does the first execution of step cache the entire result set
and tje subsequent steps get the results from the cache?

Sreekumar
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] DOMAIN new error code

2011-10-16 Thread Jean-Christophe Deschamps
I have the need to use some math extension functions.  While testing 
them I found it very difficult to select an informative error code in 
case of a domain error, like sqrt(-1).


Would it be sensible to create a new generic error code in some next 
release for extension functions to report such kind of errors?  It 
would then be easier to track down the source of the issue if such 
error code existed, rather than being confronted to the uninformative 
SQLITE_ERROR "SQL error or missing database".


Returning NULL silently is not the best choice in some cases (math 
functions for instance but it could serve other cases as well), where 
it is desirable to keep the distinction between a NULL argument (here 
returning NULL makes sense) and an out of range argument (here no 
return value makes sense).


SQLITE_MISMATCH, SQLITE_MISUSE and SQLITE_RANGE already exist but have 
precise, completely different meanings and should certainly not be used 
in those cases.


Something like:
#define SQLITE_DOMAIN  27   /* Type, format or domain error in 
extension function */


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] [patch, try 2] Re: Ambiguous column name when using multiple JOIN USING clauses and WHERE clause

2011-10-16 Thread Jeremy Evans
On Sun, Oct 16, 2011 at 3:28 PM, Yuriy Kaminskiy  wrote:
> Thanks for testing.
> Have no idea what can trigger sigsegv here.
> Patch applied with any rejects/offsets/fuzziness?

Error on my end.  I had to hand apply the patch and I did it wrong,
sorry.  Everything looks good now that I applied it correctly.

Thanks,
Jeremy
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] [patch, try 2] Re: Ambiguous column name when using multiple JOIN USING clauses and WHERE clause

2011-10-16 Thread Yuriy Kaminskiy
Jeremy Evans wrote:
> On Sat, Oct 15, 2011 at 11:46 PM, Yuriy Kaminskiy  wrote:
> 7> Whoops, patch eaten by hungry ewoks. Hopefully, inlining will work better:
>> Subject: fix false "ambiguous column" detection in multiple JOIN USING
>>
>> Instead of skipping only *next* table, we ignore matches when we have exactly
>> one match before and we joined to *previous* table with JOIN USING/NATURAL 
>> JOIN.
>> So,
>> CREATE TABLE a(i, j);
>> CREATE TABLE b(j);
>> CREATE TABLE c(i);
>> CREATE TABLE d(j);
>> SELECT * FROM a JOIN b USING(j) JOIN c USING(i) JOIN d USING(j)
>> should work properly.
>>
>> The author or authors of this code dedicate any and all copyright interest
>> in this code to the public domain. We make this dedication for the benefit
>> of the public at large and to the detriment of our heirs and successors.
>> We intend this dedication to be an overt act of relinquishment in perpetuity
>> of all present and future rights to this code under copyright law.
>>
>> Signed-off-by: Yuriy M. Kaminskiy 
>>
>> Index: sqlite3-3.7.8/src/resolve.c
>> ===
>> --- sqlite3-3.7.8.orig/src/resolve.c2011-10-16 09:18:20.0 +0400
>> +++ sqlite3-3.7.8/src/resolve.c 2011-10-16 09:39:53.0 +0400
>> @@ -190,33 +190,34 @@ static int lookupName(
>> for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){
>>   if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
>> IdList *pUsing;
>> -cnt++;
>> -pExpr->iTable = pItem->iCursor;
>> -pExpr->pTab = pTab;
>> -pMatch = pItem;
>> -pSchema = pTab->pSchema;
>> -/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY 
>> */
>> -pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
>> -if( inSrc-1 ){
>> -  if( pItem[1].jointype & JT_NATURAL ){
>> +if( cnt == 1 ){

out of paranoia:
   +  assert( i>0 );
   +  assert( pItem->jointype!=0 );
(but both should be completely impossible)

>> +  /* We already met this name once in some previous table(s),
>> +  ** but... */
>> +  if( pItem->jointype & JT_NATURAL ){
>> /* If this match occurred in the left table of a natural 
>> join,
>> ** then skip the right table to avoid a duplicate match */
>> -pItem++;
>> -i++;
>> -  }else if( (pUsing = pItem[1].pUsing)!=0 ){
>> +continue;
>> +  }else if( (pUsing = pItem->pUsing)!=0 ){
>> /* If this match occurs on a column that is in the USING 
>> clause
>> ** of a join, skip the search of the right table of the join
>> ** to avoid a duplicate match there. */
>> int k;
>> for(k=0; knId; k++){
>>   if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
>> -pItem++;
>> -i++;
>> break;
>>   }
>> }
>> +if( k!=pUsing->nId )
>> +  continue;
fwiw, I think both "continue;" can be replaced with "break;"
>>   }
>> }
>> +cnt++;
>> +pExpr->iTable = pItem->iCursor;
>> +pExpr->pTab = pTab;
>> +pMatch = pItem;
>> +pSchema = pTab->pSchema;
>> +/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY 
>> */
>> +pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
>> break;
>>   }
>> }
> 
> I tried this patch and it does appear to fix the issue, but I'm also
> getting occasional segfaults in lookupName after applying it.

Thanks for testing.
Have no idea what can trigger sigsegv here.
Patch applied with any rejects/offsets/fuzziness?

`make test` shown no problem. `make fulltest` got some problems:

prepare.analyze3-1.1.8...
Expected: [999 999 499500]
 Got: [2000 0 499500]
prepare.analyze3-1.1.9...
Expected: [999 999 499500]
 Got: [2000 0 499500]
...
11 errors out of 2630788 tests
Failures on these tests: prepare.analyze3-1.1.8 prepare.analyze3-1.1.9
prepare.analyze3-1.2.8 prepare.analyze3-1.2.9 prepare.analyze3-1.3.8
prepare.analyze3-1.3.9 prepare.analyze3-2.4 prepare.analyze3-2.6
prepare.analyze3-2.7 prepare.analyze3-2.8 prepare.analyze3-2.9

... but they fails for me even with patch reverted.

And no segfaults.

Running few simple tests under valgrind have not produced anything suspicious.

> Haven't built a debug version of SQLite yet to determine exactly where.

I think SQL statement triggering segv would be enough.

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Petite Abeille

On Oct 16, 2011, at 10:39 PM, Kit wrote:

>> select count(*) from (select 1 from table limit 5000)
> 
> SELECT count(1) FROM (SELECT 1 FROM table LIMIT 5000);

you realize that count( * )  has a very specific meaning, right?

"The count(*) function (with no arguments) returns the total number of rows in 
the group."

http://www.sqlite.org/lang_aggfunc.html

If this is what you mean, then stick to it :)

http://stackoverflow.com/questions/2710621/count-vs-count1-vs-countpk-which-is-better/2710703#2710703

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Kit
> select count(*) from (select 1 from table limit 5000)

SELECT count(1) FROM (SELECT 1 FROM table LIMIT 5000);
-- 
Kit
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Column headers include subselect alias if column is from a subselect

2011-10-16 Thread Jeremy Evans
I'm not sure if this is expected/desired behavior, but I think it is incorrect:

$ sqlite3
SQLite version 3.7.8 2011-09-19 14:49:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .headers ON
sqlite> CREATE TABLE b (a integer);
sqlite> INSERT INTO b VALUES (1);
sqlite> SELECT * FROM b;
a
1
sqlite> SELECT b.a FROM b;
a
1
sqlite> SELECT c.a FROM b AS c;
a
1
sqlite> SELECT c.a FROM (SELECT * FROM b) AS c;
c.a
1
sqlite> SELECT c.a FROM b JOIN b AS c USING(a);
a
1
sqlite> SELECT c.a FROM b JOIN (SELECT * FROM b) AS c USING(a);
c.a
1

Note how if the column comes from a subselect, the subselect alias
qualifier is included in the column header.

I would expect a column header of a for all of these queries, and all
other databases I've tested with use a column header of a.  Is this a
bug in SQLite?

Jeremy
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] [patch, try 2] Re: Ambiguous column name when using multiple JOIN USING clauses and WHERE clause

2011-10-16 Thread Jeremy Evans
On Sat, Oct 15, 2011 at 11:46 PM, Yuriy Kaminskiy  wrote:
7> Whoops, patch eaten by hungry ewoks. Hopefully, inlining will work better:
>
> Subject: fix false "ambiguous column" detection in multiple JOIN USING
>
> Instead of skipping only *next* table, we ignore matches when we have exactly
> one match before and we joined to *previous* table with JOIN USING/NATURAL 
> JOIN.
> So,
> CREATE TABLE a(i, j);
> CREATE TABLE b(j);
> CREATE TABLE c(i);
> CREATE TABLE d(j);
> SELECT * FROM a JOIN b USING(j) JOIN c USING(i) JOIN d USING(j)
> should work properly.
>
> The author or authors of this code dedicate any and all copyright interest
> in this code to the public domain. We make this dedication for the benefit
> of the public at large and to the detriment of our heirs and successors.
> We intend this dedication to be an overt act of relinquishment in perpetuity
> of all present and future rights to this code under copyright law.
>
> Signed-off-by: Yuriy M. Kaminskiy 
>
> Index: sqlite3-3.7.8/src/resolve.c
> ===
> --- sqlite3-3.7.8.orig/src/resolve.c    2011-10-16 09:18:20.0 +0400
> +++ sqlite3-3.7.8/src/resolve.c 2011-10-16 09:39:53.0 +0400
> @@ -190,33 +190,34 @@ static int lookupName(
>         for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){
>           if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
>             IdList *pUsing;
> -            cnt++;
> -            pExpr->iTable = pItem->iCursor;
> -            pExpr->pTab = pTab;
> -            pMatch = pItem;
> -            pSchema = pTab->pSchema;
> -            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY 
> */
> -            pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
> -            if( inSrc-1 ){
> -              if( pItem[1].jointype & JT_NATURAL ){
> +            if( cnt == 1 ){
> +              /* We already met this name once in some previous table(s),
> +              ** but... */
> +              if( pItem->jointype & JT_NATURAL ){
>                 /* If this match occurred in the left table of a natural join,
>                 ** then skip the right table to avoid a duplicate match */
> -                pItem++;
> -                i++;
> -              }else if( (pUsing = pItem[1].pUsing)!=0 ){
> +                continue;
> +              }else if( (pUsing = pItem->pUsing)!=0 ){
>                 /* If this match occurs on a column that is in the USING 
> clause
>                 ** of a join, skip the search of the right table of the join
>                 ** to avoid a duplicate match there. */
>                 int k;
>                 for(k=0; knId; k++){
>                   if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
> -                    pItem++;
> -                    i++;
>                     break;
>                   }
>                 }
> +                if( k!=pUsing->nId )
> +                  continue;
>               }
>             }
> +            cnt++;
> +            pExpr->iTable = pItem->iCursor;
> +            pExpr->pTab = pTab;
> +            pMatch = pItem;
> +            pSchema = pTab->pSchema;
> +            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY 
> */
> +            pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
>             break;
>           }
>         }

I tried this patch and it does appear to fix the issue, but I'm also
getting occasional segfaults in lookupName after applying it.  Haven't
built a debug version of SQLite yet to determine exactly where.

Jeremy
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] sqlite_stat3

2011-10-16 Thread GB

Hi,

just noticed the timeline comments concerning sqlite_stat3. Will the new 
code also regard the INTEGER PRIMARY KEY "index" distribution?


regards
gerd
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Petite Abeille

On Oct 16, 2011, at 1:09 PM, Fabian wrote:

> How can you limit a count-query? I tried:
> 
> SELECT COUNT(*) FROM table LIMIT 5000
> 
> But it ignores the LIMIT clause. 

No it doesn't, it works as advertised. You are falling into the same trap as 
you did just a couple of threads ago. You need to get a grip on that LIMIT 
construct :)

The fine manual is there to help, please see "ORDER BY and LIMIT/OFFSET 
Clauses":

http://www.sqlite.org/lang_select.html

In the meantime:

select count( * )
from   (
 select 1
 fromtable
 limit 5000
   )


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Frank Missel
> boun...@sqlite.org] On Behalf Of Simon Slavin
> Sent: 16 October 2011 21:53
> 
> Perhaps he could read the rows LIMIT 100 into a buffer (after all, he's
going
> to need them eventually for when he displays them), then count how many
> rows he got.

Yeah, I would go that way also.

But it sounds a bit like Fabian both wants to have the total number of
records available and at the same time limit the count.
It is just not possible to do both at the same time as far as I can see.

Thus, you are left with following options as far as I can see:

1. As Slavin mentions: Read a certain number of records, e.g. 101 and change
your code so that the user can ask for e.g. 100 additional records at a
time. Possibly you could have an extra function that the user could activate
to have a total count if he so wishes. This would then read all records and
you would not have to worry about performance as all records (unless there
are very many) will be in the memory cache and subsequent request for these
records should be fast.

2. If there are many concurrent users and the query requests from these are
quite predictable, e.g. straight reads of all records in certain tables, you
could perhaps  have a local background job regularly count the number of
records for the relevant tables/queries and store these count results  in a
special status table. Your client program could then read the number of
records from the special status table as well as the first 101 records from
the actual data carrying table. The user could then get the first 100
records, and continue with batches of 100 as needed.

If these options does not seem to fit, I think that you have to explain a
bit more about how your solution is,  what you expect and how you access the
database.


/Frank


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Roger Andersson

 On 10/16/11 14:21, Fabian wrote:

I want to allow users to paginate through a result set. The pages are
retreived through LIMIT/OFFSET, but to calculate the total number of pages,
I have execute a separate COUNT() query (without LIMIT) once.

Because I'm basicly executing the same query twice just to get a total
count, I'm trying to optimize this. Restricting the maximum number of pages
to 10 should improve performance, if there was some way to put make COUNT()
respect the LIMIT specified.
___

I can't tell if this is more efficient but it's one query
select *,(select count(*) from table) as total_record_count from table 
limit 100;

/Roger
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] IT Test message - please ignore and remove

2011-10-16 Thread Ilya Bar-Haim



___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Simon Slavin

On 16 Oct 2011, at 2:50pm, Bart Smissaert wrote:

> He is trying to make it more efficient, so stop counting if count > X.
> So setting the count after having counted the whole lot won't help.

Then he can't use count() because SQLite's implementation of it is not 
efficient for that.

Perhaps he could read the rows LIMIT 100 into a buffer (after all, he's going 
to need them eventually for when he displays them), then count how many rows he 
got.

Simon.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Bart Smissaert
He is trying to make it more efficient, so stop counting if count > X.
So setting the count after having counted the whole lot won't help.

RBS


On Sun, Oct 16, 2011 at 2:46 PM, Simon Slavin  wrote:
>
> On 16 Oct 2011, at 1:21pm, Fabian wrote:
>
>> 2011/10/16 Frank Missel 
>>
>>> What do you want to attain with the count?
>>
>> I want to allow users to paginate through a result set. The pages are
>> retreived through LIMIT/OFFSET, but to calculate the total number of pages,
>> I have execute a separate COUNT() query (without LIMIT) once.
>
> You're using a programming language.  So do this:
>
> numberOfRows = SELECT count(*) FROM myTable
> if (numberOfRows > 100) then numberOfRows = 100
>
> Simon.
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Simon Slavin

On 16 Oct 2011, at 1:21pm, Fabian wrote:

> 2011/10/16 Frank Missel 
> 
>> What do you want to attain with the count?
> 
> I want to allow users to paginate through a result set. The pages are
> retreived through LIMIT/OFFSET, but to calculate the total number of pages,
> I have execute a separate COUNT() query (without LIMIT) once.

You're using a programming language.  So do this:

numberOfRows = SELECT count(*) FROM myTable
if (numberOfRows > 100) then numberOfRows = 100

Simon.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Roger Andersson

 On 10/16/11 14:21, Fabian wrote:

I want to allow users to paginate through a result set. The pages are
retreived through LIMIT/OFFSET, but to calculate the total number of pages,
I have execute a separate COUNT() query (without LIMIT) once.

Because I'm basicly executing the same query twice just to get a total
count, I'm trying to optimize this. Restricting the maximum number of pages
to 10 should improve performance, if there was some way to put make COUNT()
respect the LIMIT specified.
___

Maybe GROUP BY and HAVING can help you?
/Roger
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Fabian
2011/10/16 Frank Missel 

>
> What do you want to attain with the count?
>
>
I want to allow users to paginate through a result set. The pages are
retreived through LIMIT/OFFSET, but to calculate the total number of pages,
I have execute a separate COUNT() query (without LIMIT) once.

Because I'm basicly executing the same query twice just to get a total
count, I'm trying to optimize this. Restricting the maximum number of pages
to 10 should improve performance, if there was some way to put make COUNT()
respect the LIMIT specified.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Jos Groot Lipman
 
SELECT COUNT(*) FROM table will always return exactly 1 record (with the
count).

LIMIT 5000 limits the number of records returned to 5000.

As 1 record < 5000 records the 5000 is effecively ignored
--
Jos
-Original Message-
From: sqlite-users-boun...@sqlite.org
[mailto:sqlite-users-boun...@sqlite.org] On Behalf Of Fabian
Sent: zondag 16 oktober 2011 13:09
To: General Discussion of SQLite Database
Subject: [sqlite] Limit COUNT

How can you limit a count-query? I tried:

SELECT COUNT(*) FROM table LIMIT 5000

But it ignores the LIMIT clause. I think the workaround would be counting
the results of a sub-query, but I'm trying to understand whats wrong with
the syntax above. The goal is to make the engine stop iterating after it
reached the upper limit, in order to save performance.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Limit COUNT

2011-10-16 Thread Frank Missel
Hi Fabian,

The problem is that the limit apparently is applied on the result set, and
in this case the result set is only one row which is less than the 5000.
The culprit is the count(*) which basically says that to get the first row
in the result set all rows from the table has to be processed.

You could instead try:

select count(*)
from (select * from table limit 500)
;

That would give you the number 500. But it is kind of meaningless.
You might as well write:

select *
from table 
limit 500
;

And get the actual 500 first rows. In this case the result set is build up
as the select statement processing loops through the records in the table,
and thus it only needs to take 500 rows. Again, if you add a count(*) it
needs to traverse all records to get the first and only row  of the result
set that states the number of records in the table. It is the same if you
specify ORDER BY together with limit. You will only get the x number of
records in the LIMIT statement but before that all records will have to be
traversed and sorted before you the 500 rows, unless perhaps there already
is an index with one component fitting the ORDER BY perfectly.

What do you want to attain with the count?

/Frank

> -Original Message-
> From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users-
> boun...@sqlite.org] On Behalf Of Fabian
> Sent: 16 October 2011 19:09
> To: General Discussion of SQLite Database
> Subject: [sqlite] Limit COUNT
> 
> How can you limit a count-query? I tried:
> 
> SELECT COUNT(*) FROM table LIMIT 5000
> 
> But it ignores the LIMIT clause. I think the workaround would be counting
the
> results of a sub-query, but I'm trying to understand whats wrong with the
> syntax above. The goal is to make the engine stop iterating after it
reached
> the upper limit, in order to save performance.
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Limit COUNT

2011-10-16 Thread Fabian
How can you limit a count-query? I tried:

SELECT COUNT(*) FROM table LIMIT 5000

But it ignores the LIMIT clause. I think the workaround would be counting
the results of a sub-query, but I'm trying to understand whats wrong with
the syntax above. The goal is to make the engine stop iterating after it
reached the upper limit, in order to save performance.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Changing the data type of an existing table

2011-10-16 Thread Frank Missel
Hi Dan,

> The two values in table "t" are stored in integer form. Were you to
magically
> change the database schema without rebuilding the underlying
> b-trees:
> 
>CREATE TABLE t(a TEXT);
> 
> and then execute the same SELECT, it would not work. SQLite would search
> the index for text value '1', not integer value 1 (since it assumes that
all
> values had the TEXT affinity applied to them when they were inserted). And
> the query would return no rows.

You are right. However, in my case it is a bit special in that the values in
the fields actually already are stored correctly as REAL numbers but because
the declared data type is DECIMAL (which is used in some databases), Excel
will not treat the real numbers as such. Changing the declared data type
does the trick!

As for text to integer as in your example, I guess it could also be done.
First the declared data type could be changed as I have described. After
that an update statement could set the  = CAST( as INTEGER).
But you are right that indexes in this case would have to be rebuilt with
the REINDEX statement. However, that might still be better than having to
recreate the whole table and build indexes.


/Frank

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Changing the data type of an existing table

2011-10-16 Thread Frank Missel
> -Original Message-
> From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users-
> boun...@sqlite.org] On Behalf Of Frank Missel
> Sent: 16 October 2011 15:37
> 
> With this open philosophy of the SQLite database I thought that perhaps
> there really isn't any compelling reason to disallow changing the declared
> data type of an existing column since the actual stored data of a column
> might be of any type - again, according to the basic philosophy of SQLite.
> Thus changing a declared data type of an existing column should not break
> anything between the schema and the stored data. But I am not sure if it
is
> even possible. If not, I will move my many Gigabytes of data around, but I
> thought, it would be worth just checking first.

Well, I looked a bit more into it and found that indeed the declared data
type of a column in an existing table can be changed without breaking
anything. In the example below the data type "DECIMAL" is changed to "REAL"
(which will make the real numbers transferred to Excel via the ODBC driver
behave as such):

1. Backup the database

2. SQL statement: 
pragma writable_schema = 1;

3. SQL statement: 
update sqlite_master
set sql = replace(sql, 'DECIMAL', 'REAL   ')
where type = 'table'
and sql like '%decimal%'
;

4. 2. SQL statement: 
pragma writable_schema = 0;

Notice the three spaces after REAL. They are not really needed but in case
there are extra field attributes after the data type in the CREATE TABLE
statement and the attributes are column aligned, the alignment will be
retained after the change.

I guess other aspects of the tables can also be changed, e.g. renaming
columns -- but here one has to remember any indexes, constraints, etc. So
that is a bit more daring but probably doable. For dropping columns one
needs to copy the data to a new table as far as I can see.

I take a bow: Hurrah for SQLite. This is truly magnificent!

WARNING:
Be sure make a backup copy of the database before doing anything as changing
the schema can corrupt it.
Any tinkering with the sqlite_master table is done at your own risk. Don't
blame me if anything goes wrong :-).

Also, I tried out the above on a small test database of the same structure
as a production database and after changing contents of sqlite_master I
tested various statements against the database to see that everything worked
as it should.

I will wait a while before changing my production databases, just in case
someone might see anything wrong with the above.


/Frank Missel


___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Changing the data type of an existing table

2011-10-16 Thread Dan Kennedy

On 10/16/2011 02:37 PM, Frank Missel wrote:


When I first learned about SQLite I never like the relaxed handling of data
where column data types from the schema are not enforced strictly on the
actual data in the tables. This felt instinctively wrong as it is very
contrary to other databases and many programming languages that I have
worked with. However, I have come to appreciate SQLite as a powerful data
container that you can use to handle data in various ways according to need.
With e.g. check restraints one can enforce data types on columns at a basic
level. On the other hand, it is sometimes more useful to just let data enter
the database and then later on use data validation to the extent that it is
needed.



With this open philosophy of the SQLite database I thought that perhaps
there really isn't any compelling reason to disallow changing the declared
data type of an existing column since the actual stored data of a column
might be of any type - again, according to the basic philosophy of SQLite.
Thus changing a declared data type of an existing column should not break
anything between the schema and the stored data. But I am not sure if it is
even possible. If not, I will move my many Gigabytes of data around, but I
thought, it would be worth just checking first.


I'm not sure I completely understand the question (is there one?),
but consider this:

  CREATE TABLE t(a INTEGER);
  CREATE INDEX i ON t(a);
  INSERT INTO t VALUES(1);
  INSERT INTO t VALUES(2);

Then:

  SELECT * FROM t WHERE a=1;

The two values in table "t" are stored in integer form. Were you to
magically change the database schema without rebuilding the underlying
b-trees:

  CREATE TABLE t(a TEXT);

and then execute the same SELECT, it would not work. SQLite would search
the index for text value '1', not integer value 1 (since it assumes
that all values had the TEXT affinity applied to them when they were
inserted). And the query would return no rows.

If you use 3.7.8, and delay creating any indexes until after all
the data has been inserted into the new tables, SQLite will use
an external merge-sort to build the new indexes. This should be much
faster than using an earlier version.



___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Changing the data type of an existing table

2011-10-16 Thread Frank Missel
Unfortunately, a need has arisen to change the data type of columns in
existing tables in some quite large databases. This is due to the fact that
Excel does not take kindly to data received from the SQLite ODBC driver
unless they are of a certain data type (the declared name), i.e. the data
are not perceived as the right type and so e.g. numerical summary functions
will not work.

 

The issue is covered by this thread:

http://www.mail-archive.com/sqlite-users@sqlite.org/msg64714.html

 

This is the reason why I would want to change the data type of existing
columns. Otherwise, I guess it would not matter that much as the types of
SQLite are bound to the actual data values and not the columns in the schema
which only have a data type affinity. 

 

Instead of changing the data type I could of course just enclose all columns
in CAST statements when selecting data to Excel. However, I prefer to only
have to do that when including expressions. Also, I have updated the frame
work that I use to handle SQLite databases so that any future tables will
only declare data types that will work correctly towards Excel. Thus I now
wish to make sure that all existing databases conform with these data types.

 

I was just about to write some code to browse through a data base, find all
tables with columns declared as a certain data type  to be changed and then
move the data over to a new identical table (but defined with the new data
type for the relevant columns). However, before going through this exercise
I thought I would just ask if any one knew of a better way to do this, as
there are several quite large databases to be so handled.

 

When I first learned about SQLite I never like the relaxed handling of data
where column data types from the schema are not enforced strictly on the
actual data in the tables. This felt instinctively wrong as it is very
contrary to other databases and many programming languages that I have
worked with. However, I have come to appreciate SQLite as a powerful data
container that you can use to handle data in various ways according to need.
With e.g. check restraints one can enforce data types on columns at a basic
level. On the other hand, it is sometimes more useful to just let data enter
the database and then later on use data validation to the extent that it is
needed.

 

With this open philosophy of the SQLite database I thought that perhaps
there really isn't any compelling reason to disallow changing the declared
data type of an existing column since the actual stored data of a column
might be of any type - again, according to the basic philosophy of SQLite.
Thus changing a declared data type of an existing column should not break
anything between the schema and the stored data. But I am not sure if it is
even possible. If not, I will move my many Gigabytes of data around, but I
thought, it would be worth just checking first.

 

 

/Frank Missel

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Time and date functions

2011-10-16 Thread Nando
Thank you all. The solution of Jean-Christophe  is perfect  and thanks to
Igor and Michael I begin to understand the logic of the processing of dates
in SQLite, which is much more powerful than it had expected at first.

sqlite> select * from fechas where fecha between date('2011-12-18','-6
days','weekday 0') and date('2011-12-18','weekday 6');

18|2011-12-18

19|2011-12-19

20|2011-12-20

21|2011-12-21

22|2011-12-22

23|2011-12-23

24|2011-12-24

sqlite> select * from fechas where fecha between date('2011-12-24','-6
days','weekday 0') and date('2011-12-24','weekday 6');

18|2011-12-18

19|2011-12-19

20|2011-12-20

21|2011-12-21

22|2011-12-22

23|2011-12-23

24|2011-12-24

sqlite> select * from fechas where fecha between date('2011-12-21','-6
days','weekday 0') and date('2011-12-21','weekday 6');

18|2011-12-18

19|2011-12-19

20|2011-12-20

21|2011-12-21

22|2011-12-22

23|2011-12-23

24|2011-12-24

Igor... I thought I was faced with a syntax problem, thanks for putting me
on track. ;)
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users