Original query: SELECT ... FROM mytable WHERE field_a IN (<list of values>)AND field_b IN (<list-of-values>) AND <key constraints>
This is sometimes (when mytable is a virtual table that offers to handle "field_a =" and "field_b =" constraints internallly) resolved as - create table eph_a - create table eph_b - full table scan eph_a - full table scan eph_b - scan table mytable index #n Target query: WITH (...) SELECT ... FROM mytable LEFT JOIN cte_a ON (mytable.a = cte_a.a) LEFT JOIN cte_b ON (mytable.b = cte_b.b) WHERE <key constraints> Which should resolve as - create table eph_a - create table eph_b - scan table mytable index #n - lookup mytable.a in eph_a - lookup mytable.b in eph_b The cost of a partial index scan is O(log n) to locate the first record and O(m) for retrieving m consecutive records. The cost of a lookup in an ephemeral table is O(log n). The cost of a full table scan for an ephemeral table is O(n) The cost of the first query plan is therefore O(a * b * (m + log n)) or O(a *b *m) + O(a * b * log n) The cost of the second query plan is only O(log n + m * (log a + log b)) or O((log a*b) * m) + O(log n) This makes the second query plan much less costly for IN lists of 2 or more elements. -----Ursprüngliche Nachricht----- Von: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im Auftrag von Dominique Devienne Gesendet: Donnerstag, 06. Dezember 2018 11:32 An: General Discussion of SQLite Database <sqlite-users@mailinglists.sqlite.org> Betreff: Re: [sqlite] [EXTERNAL] Re: sqlite3_bind_text() and WHERE x IN (?) On Thu, Dec 6, 2018 at 11:10 AM Hick Gunter <h...@scigames.at> wrote: > Maybe someone can come up with a CTE that works for this... > How so? I'm not following you. Ryan already provided a CTE to transform a string into values, but that involves string parsing, and is kinda ugly (no offence Ryan :) ), and unlikely to be that efficient relative to carray. The point is that binding is *scalar only* in SQLite. If OTOH, we could write: ...prepare...(db, "select ... from t where c in (?)", ..., &stmt, ...); ...bind_array(stmt, 1, SQLITE_INTEGER, vec.size()); for (auto elem : vec) { ...bind_int(stmt, 1, elem); } ...bind_array would instantiate the same array the carray() extension supports. Existing typed bind APIs would fill in that array, with usual SQLite conversions, error checking against declared array-type. And ...prepare would transparently transform WHERE c IN (?) with WHERE c IN (carray(?)) with the internally managed C array. Of course, at prepare time, SQLite doesn't know yet ? is not a scalar as usual, so perhaps a different notation is necessary, like the TABLE() operator in Oracle SQL for example. But given carray() and the existing infrastructure, I naively fail to see how the above wouldn't work. My $0.02. --DD [1] https://www.sqlite.org/c3ref/c_blob.html _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users ___________________________________________ Gunter Hick | Software Engineer | Scientific Games International GmbH | Klitschgasse 2-4, A-1130 Vienna | FN 157284 a, HG Wien, DVR: 0430013 | (O) +43 1 80100 - 0 May be privileged. May be confidential. Please delete if not the addressee. _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users