• ariel_mlk (9/4/2012)


    Hi people,

    I'm tunning a database and i've stumbled by some hierarchy queries, on the good old form of ID, ParentID, to work out the hierarchy the previous developers used a like logic as in

    SELECT TB1.* FROM TABLE1 as TB1 ON TABLE1 as TB2 on TB2.Hierarchy + '.' LIKE TB1.Hierarchy + '.%'

    where hierarchy field contains the "path" to the parent nodes for example

    1.2.3.4.5 would mean, this row is 5, parent is 4, grandparent is 3 and so forth

    i've rewritten that in a CTE, and the query plan shouts out at me that it takes something like 25% of the cost in batch when running the rCTE approach and the like approach ( which would lead me to think that the rCTE is by far faster than the original ) but the like clause seems to take way lesser reads, i've read somewhere that the query plan only looks at the cost of a first execution of a rCTE, but as I understand rCTE were meant for jobs like this one, so how can a nasty non-sargable like go by less reads than a rCTE ?

    sry if the post is not clear enough,

    I haven't posted the query plans in the belief that i'm just misunderstanding something, if it ain't the case, i'll promptly post those

    God that is awful. At least they are former developers so they won't continue creating stuff like that for you to work with. That is an adjacency list that is denormalized. I would start by getting rid of anything other than the immediate parent. The rest of that is nothing but pain. Once you start joining on like '%' you are in for a horrible performance. Say goodbye to indexing.

    I tossed together some very simplified ddl and and sample data to see if your problem is what I think it is.

    ;with BadAdj ( KeyVal, SomeVal, ParentKeyVal, AwfulPath)

    as

    (

    select 1, 'Top Dog', null, '1' union all

    select 2, 'Next Dog', 1, '1.2' union all

    select 3, 'Grandchild', 2, '1.2.3' union all

    select 4, 'Uber Grandchild', 3, '1.2.3.4' union all

    select 5, 'Step Grandchild', 4, '1.2.3.4.5'

    )

    select * from BadAdj

    If I understand what you are facing...you have something like AwfulPath instead of the simple ParentKeyVal? If so, do you have the ability to change the ddl into something more usable? Even if you have to leave the whole path adding a new column to identify the parent would go a long way to making this easier to work with.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/