Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Does the version of SQLite you're developing on support Foreign Keys? If so, your closure table design should have a FK referencing the hierarchy table you're supporting with the closure table. In TSQL: </p> <pre><code>constraint fk_a FOREIGN KEY (ancestor) REFERENCES &lt;hierarchy_tablename&gt; (nodeid) constraint fk_d FOREIGN KEY (descendant) REFERENCES &lt;hierarchy_tablename&gt; (nodeid) </code></pre> <p>You'll have to look up the relevant SQLite syntax, sorry.</p> <p>Since you are already maintaining a depth field, which is the distance between the descendant and its ancestor, you could make use of it to tell if a given node has children. </p> <pre><code>select top 1 'EXPANDABLE' as whatever from closure C where exists (select ancestor from closure where depth &gt; 0 and ancestor = C.ancestor) and ancestor = @Node </code></pre> <p>That should come back fairly quick regardless of the size of your closure table. If you get an empty set from that, then your given node cannot be expanded any more, because it has no children. Exists returns true as soon as it finds one instance that meets your criteria, and you're only taking the top 1 so you don't return a row for every row in your closure table for the passed @Node. </p> <p>As for improving the performance of finding the roots, try something like the below. It's what I use for finding roots, but my closure table is only ~200,000 rows. I compared the plans generated for each though, and your code uses a Hash, which could be impacting performance due to processor requirements on the device (I'm assuming here that SQLite is for iPhone/iPad or sometype of small distribution on devices). The below uses less processing power and more reads from indexes in its plan and makes use of the relationship of the hierarchy to the closure table. I cannot be certain that it will improve your performance woes but it's worth a shot. </p> <pre><code>select a.node_name, a.node_id from test.hier a left outer join (select coo.descendant /* coo = CHILD OF OTHER */ from test.closure_tree coo right outer join test.closure_tree ro on coo.ancestor &lt;&gt; ro.descendant /* ignore its self reference */ and coo.descendant = ro.descendant /* belongs to another node besides itself */)lo on a.node_id = lo.descendant where lo.descendant is null </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload