Igor, Nice one. A quick test using 10 lookup trees and the same search criteria: *Showing rows 0 - 29 (30 total, Query took 0.4838 sec)*
Now with UNION ALL replacing UNION: *Showing rows 0 - 29 (30 total, Query took 0.2050 sec)* You weren't kidding about cheaper were you? LOL On 16 October 2014 10:30, Michael Falconer <michael.j.falco...@gmail.com> wrote: > Yes, I agree with the general sentiment. It is not exactly the design I > would have chosen either, but it is what exists. Design change is occurring > but for the moment we are stuck with the current schema. > > If you cannot change the schemata to be more suitable, then your >> demonstrated queries are very near as good as it gets. I can think of other >> ways to achieve the same, but nothing that would be more efficient to a >> tangible level. Maybe someone else here can come up with something a bit >> more tight. >> > You are preaching to the converted I'm afraid, but I appreciate the points > you made. The quoted paragraph probably answers most of my questions > really, except for this from Igor: > > Unless you do expect duplicates and need to eliminate them, use UNION ALL >> - it's much cheaper (this is assuming you insist on keeping multiple >> tables). >> > Cheaper because it drops the operation to remove the duplicate records > from the result set? I'm assuming. I'll give that a try. > > On 16 October 2014 10:05, RSmith <rsm...@rsweb.co.za> wrote: > >> >> On 2014/10/16 00:05, Michael Falconer wrote: >> >>> Hi all, >>> >>> first off I must start with an apology. I know I'm sort of doing the >>> wrong//... >>> >> >> No need to apologise, this flies quite close to the central theme. >> Whether you are using SQLite or any other SQL RDBMS, this is horrible DB >> design and it is so for precisely the reasons you are asking the question. >> Tables should not be dynamic: The simple rule of thumb being - if you >> cannot tell (or at least accurately predict) before-hand exactly how many >> tables will be in the final system, then you are doing it wrong. Why not >> have one set of tables and in stead of preceding each of them with a >> <prefix>, simply add a column that can host the <prefix> as a simple value, >> which will immediately make your life very much easier and get the SQL >> engine to do the work you are now trying to compensate for in a lop-sided >> manual kind of way. >> >> I can only imagine the amount of code you invested into your system to >> track and deal with these dynamic sets of tables, so I know changing it >> will seem like a rather large undertaking, but really it will mostly >> involve removing loads of code to end up with a small set of simple queries >> that does all the work for you. >> >> The only reason I can imagine this sort of breakdown useful is if your >> tree tables are all really really huge, like Gigabytes, and so there might >> be some efficiency to be gained from splitting it up, but I doubt this is >> the case. >> >> Just imagine the ease of those search queries you demonstrated... one >> query, no UNIONs, a single set of joins and an extra where-clause check... >> Add to that increased efficiency at finding results (run one query in stead >> of 50). Easy-mode. As a proof-of-concept, just make an SQLite DB, one set >> of tables as per your list, add column(s) for prefixing as needed, import >> all the tables from some large set of them (specifying additionally the >> column for the prefix) and ten run search queries on them. I am willing to >> bet on the fact it will be much quicker in addition to being much simpler. >> >> If you cannot change the schemata to be more suitable, then your >> demonstrated queries are very near as good as it gets. I can think of other >> ways to achieve the same, but nothing that would be more efficient to a >> tangible level. Maybe someone else here can come up with something a bit >> more tight. >> >> >> thing here as this question is NOT related to sqlite. It is a general SQL >>> question but I ask it here because I have great respect for the answers >>> and >>> discussions I have seen on this forum over many years. I rarely post >>> myself >>> as there are always several contributors who beat me to the answer and >>> often their response is far better than mine would have been. I'm not a >>> code leper, I don't need the actual SQL just the method really, though a >>> short code example would be well received for illustration. >>> >>> It's about a search performed on multiple tables. However the structure >>> of >>> this database is somewhat unorthodox. It contains genealogical data and >>> this is clustered into trees. Each tree has 8 tables, there can be as >>> many >>> as 100 trees but most installations of the associated application >>> software >>> contain between 5 - 50 trees. These 8 tables contain a family trees data >>> and are named: >>> <prefix>addresses >>> <prefix>connections >>> <prefix>events >>> <prefix>family >>> <prefix>person >>> <prefix>repositories >>> <prefix>sources >>> <prefix>texts >>> >>> The <prefix> changes and is unique for each tree. >>> >>> There are extensive search options offered to users as well as simple >>> name >>> searching and it is one of the best features of the app. It works pretty >>> well, so it ain't broke in any sense, we just wonder if there is a better >>> way to perform this search in SQL. Is there a general technique which is >>> superior either in speed, efficiency or load bearing contexts? >>> >>> I am sure you can see one of the pitfalls here is the exponential growth >>> of >>> such a search query as both total number of trees and indeed user search >>> criteria increase. For each criteria component, and there are quite a >>> few, >>> the appropriate tables must be queried and results joined. >>> >>> Searches return records of individuals meeting the entered search >>> criteria >>> so the query focuses on the person table as it's anchor, performs >>> searches >>> on required other tables in the tree and joins the results to the person >>> data. The results from each tree search are then UNION'ed to provide the >>> result set. Here is a contrived example of the SQL query code which >>> should >>> make things clearer. >>> >>> The user enters simple search criteria - any person with a last name >>> containing 'mac' and a first name containing the character 'a'. This is >>> the >>> resulting query (generated by php code), which searches a small 4 family >>> tree installation. >>> >>> (SELECT humo1_person.*, event_kind, event_event, address_place, >>> address_zip >>> FROM humo1_person >>> LEFT JOIN humo1_events ON pers_gedcomnumber=event_person_id >>> LEFT JOIN humo1_addresses ON pers_gedcomnumber=address_person_id >>> WHERE pers_lastname LIKE '%mac%' >>> AND (pers_firstname LIKE '%a%' >>> OR (event_kind='name' AND event_event LIKE '%a%') >>> ) >>> GROUP BY pers_gedcomnumber >>> ) >>> UNION >>> (SELECT humo2_person.*, event_kind, event_event, address_place, >>> address_zip >>> FROM humo2_person LEFT JOIN humo2_events ON >>> pers_gedcomnumber=event_person_id >>> LEFT JOIN humo2_addresses ON pers_gedcomnumber=address_ >>> person_id >>> WHERE pers_lastname LIKE '%mac%' >>> AND (pers_firstname LIKE '%a%' >>> OR (event_kind='name' AND event_event LIKE '%a%') ) >>> GROUP BY pers_gedcomnumber >>> ) >>> UNION >>> (SELECT humo3_person.*, event_kind, event_event, address_place, >>> address_zip >>> FROM humo3_person LEFT JOIN humo3_events ON >>> pers_gedcomnumber=event_person_id >>> LEFT JOIN humo3_addresses ON pers_gedcomnumber=address_ >>> person_id >>> WHERE pers_lastname LIKE '%mac%' >>> AND (pers_firstname LIKE '%a%' >>> OR (event_kind='name' AND event_event LIKE '%a%') >>> ) >>> GROUP BY pers_gedcomnumber >>> ) >>> UNION >>> (SELECT humo4_person.*, event_kind, event_event, address_place, >>> address_zip >>> FROM humo4_person >>> LEFT JOIN humo4_events ON pers_gedcomnumber=event_person_id >>> LEFT JOIN humo4_addresses ON pers_gedcomnumber=address_ >>> person_id >>> WHERE pers_lastname LIKE '%mac%' >>> AND (pers_firstname LIKE '%a%' >>> OR (event_kind='name' AND event_event LIKE '%a%') >>> ) >>> GROUP BY pers_gedcomnumber >>> ) >>> ORDER BY pers_lastname ASC , pers_firstname ASC LIMIT 0,30 >>> >>> Any thoughts? Suggestions? Missiles? Good approach, bad approach, or >>> completely off the grid? I do use sqlite quite a bit, but not on this >>> particular project. >>> >>> >>> >> _______________________________________________ >> sqlite-users mailing list >> sqlite-users@sqlite.org >> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >> > > > > -- > Regards, > Michael.j.Falconer. > -- Regards, Michael.j.Falconer. _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users