Re: [PERFORM] Nested loop Query performance on PK
Hello, Le 26/07/09 7:09, Greg Caulton a écrit : On Sun, Jul 26, 2009 at 1:02 AM, Greg Caulton caulton...@gmail.com mailto:caulton...@gmail.com wrote: Hello, It seems to me that the following query should be a lot faster. This runs in 17 seconds (regardless how many times I run it) select ac.* from application_controls_view ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%XYZ%'; [...] Does this seem right to you? Anything I can tune ? [...] Oh it seems to be the join that is throwing it off, because this runs in 600 ms select ac.* from application_controls_view ac where ac.application_control_id in ( 5745, 5760, [...] 50021066, 50020808 ) never mind, makes sense now - its fixed [...] The following rewritten query may be satisfiable for the generic case of using arbitrary LIKE pattern for refs.ref_key and performing in a short acceptable time as well: SELECT ac.* FROM application_controls_view AS ac INNER JOIN ( SELECT ref_id FROM refs WHERE ref_key LIKE '%XYZ%' ) AS r ON ac.custom_controller_ref_id = r.ref_id; The hint is to build a subquery, from refs table, and to move in the WHERE clause that only refers to refs column (ref_key here). This subquery results in a shorter table than the original (refs here), thence reducing the number of joins to perform with ac (no matter working with view or original table). Regards. -- nha / Lyon / France. -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance
[PERFORM] Nested loop Query performance on PK
Hello, It seems to me that the following query should be a lot faster. This runs in 17 seconds (regardless how many times I run it) select ac.* from application_controls_view ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%XYZ%'; if I do not use the view the query runs in under 100 ms select ac.* from application_controls ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%XYZ%'; The view is SELECT t.action_form_type_ref_id, r1.display AS action_form_type_display, t.action_order_type_ref_id, r2.display AS action_order_type_display, t.action_view_ref_id, r3.display AS action_view_display, t.active_ind, t.application_control_id, t.application_control_name, t.application_view_id, t.background_color, t.background_processing_ind, t.base_model_type_ref_id, r4.display AS base_model_type_display, t.base_value_script, t.class_instantiate_script, t.class_name, t.combo_add_to_list_ind, t.combo_category_ref_id, r5.display AS combo_category_display, t.combo_dynamic_search_ind, t.combo_filter_ref_id, r6.display AS combo_filter_display, t.combo_group_ref_id, r7.display AS combo_group_display, t.combo_short_display_ind, t.combo_values_term_id, t.comparison_operator_ref_id, r8.display AS comparison_operator_display, t.context_ref_id, r9.display AS context_display, t.control_description, t.control_format, t.control_format_ref_id, r10.display AS snip for brevity t.parameter_ref_id = r30.ref_id AND t.parameter_source_ref_id = r31.ref_id AND t.record_item_ref_id = r32.ref_id AND t.repeating_section_view_ref_id = r33.ref_id AND t.report_print_ref_id = r34.ref_id AND t.right_arrow_action_ref_id = r35.ref_id AND t.right_click_action_ref_id = r36.ref_id AND t.section_view_ref_id = r37.ref_id AND t.select_action_ref_id = r38.ref_id AND t.source_ref_id = r39.ref_id AND t.state_field_type_ref_id = r40.ref_id AND t.table_access_ref_id = r41.ref_id AND t.update_user_ref_id = r42.ref_id AND t.value_data_type_ref_id = r43.ref_id; so basically it joins 43 times to the refs table on the primary key the explain confirms the nested loops {NESTLOOP :startup_cost 2660771.70 :total_cost 3317979.85 :plan_rows 27 :plan_width 4708 :targetlist ( {TARGETENTRY :expr {VAR :varno 65001 :varattno 29 :vartype 20 :vartypmod -1 :varlevelsup 0 :varnoold 5 snip for brevity - Index Scan using refs_pk on refs r17 (cost=0.00..5.45 rows=1 width=50) Index Cond: (r17.ref_id = t.detail_record_item_ref_id) - Index Scan using refs_pk on refs r1 (cost=0.00..5.45 rows=1 width=50) Index Cond: (r1.ref_id = t.action_form_type_ref_id) - Index Scan using refs_pk on refs r (cost=0.00..5.45 rows=1 width=8) Index Cond: (r.ref_id = t.custom_controller_ref_id) Filter: ((r.ref_key)::text ~~ '%ERNEST%'::text) I did a vacuum analyze and so the primary key (indexes of course) is being used. But the above query is still 17s. If I dont return so many columns it comes down to around 10 seconds. select ac.application_control_id from application_controls_view ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%ERNEST%'; But in either case this is only 37 rows. So 1554 lookups on a unique index on a table of 34000 rows means 6ms per internal join - note that many of those values are the same. Does this seem right to you? Anything I can tune ? -- Gregory Caulton Principal at PatientOS Inc. personal email: caulton...@gmail.com http://www.patientos.com corporate: (888)-NBR-1EMR || fax 857.241.3022
Re: [PERFORM] Nested loop Query performance on PK
On Sun, Jul 26, 2009 at 1:02 AM, Greg Caulton caulton...@gmail.com wrote: Hello, It seems to me that the following query should be a lot faster. This runs in 17 seconds (regardless how many times I run it) select ac.* from application_controls_view ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%XYZ%'; if I do not use the view the query runs in under 100 ms select ac.* from application_controls ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%XYZ%'; The view is SELECT t.action_form_type_ref_id, r1.display AS action_form_type_display, t.action_order_type_ref_id, r2.display AS action_order_type_display, t.action_view_ref_id, r3.display AS action_view_display, t.active_ind, t.application_control_id, t.application_control_name, t.application_view_id, t.background_color, t.background_processing_ind, t.base_model_type_ref_id, r4.display AS base_model_type_display, t.base_value_script, t.class_instantiate_script, t.class_name, t.combo_add_to_list_ind, t.combo_category_ref_id, r5.display AS combo_category_display, t.combo_dynamic_search_ind, t.combo_filter_ref_id, r6.display AS combo_filter_display, t.combo_group_ref_id, r7.display AS combo_group_display, t.combo_short_display_ind, t.combo_values_term_id, t.comparison_operator_ref_id, r8.display AS comparison_operator_display, t.context_ref_id, r9.display AS context_display, t.control_description, t.control_format, t.control_format_ref_id, r10.display AS snip for brevity t.parameter_ref_id = r30.ref_id AND t.parameter_source_ref_id = r31.ref_id AND t.record_item_ref_id = r32.ref_id AND t.repeating_section_view_ref_id = r33.ref_id AND t.report_print_ref_id = r34.ref_id AND t.right_arrow_action_ref_id = r35.ref_id AND t.right_click_action_ref_id = r36.ref_id AND t.section_view_ref_id = r37.ref_id AND t.select_action_ref_id = r38.ref_id AND t.source_ref_id = r39.ref_id AND t.state_field_type_ref_id = r40.ref_id AND t.table_access_ref_id = r41.ref_id AND t.update_user_ref_id = r42.ref_id AND t.value_data_type_ref_id = r43.ref_id; so basically it joins 43 times to the refs table on the primary key the explain confirms the nested loops {NESTLOOP :startup_cost 2660771.70 :total_cost 3317979.85 :plan_rows 27 :plan_width 4708 :targetlist ( {TARGETENTRY :expr {VAR :varno 65001 :varattno 29 :vartype 20 :vartypmod -1 :varlevelsup 0 :varnoold 5 snip for brevity - Index Scan using refs_pk on refs r17 (cost=0.00..5.45 rows=1 width=50) Index Cond: (r17.ref_id = t.detail_record_item_ref_id) - Index Scan using refs_pk on refs r1 (cost=0.00..5.45 rows=1 width=50) Index Cond: (r1.ref_id = t.action_form_type_ref_id) - Index Scan using refs_pk on refs r (cost=0.00..5.45 rows=1 width=8) Index Cond: (r.ref_id = t.custom_controller_ref_id) Filter: ((r.ref_key)::text ~~ '%ERNEST%'::text) I did a vacuum analyze and so the primary key (indexes of course) is being used. But the above query is still 17s. If I dont return so many columns it comes down to around 10 seconds. select ac.application_control_id from application_controls_view ac, refs r where ac.custom_controller_ref_id = r.ref_id and r.ref_key like '%ERNEST%'; But in either case this is only 37 rows. So 1554 lookups on a unique index on a table of 34000 rows means 6ms per internal join - note that many of those values are the same. Does this seem right to you? Anything I can tune ? -- Gregory Caulton Principal at PatientOS Inc. personal email: caulton...@gmail.com http://www.patientos.com corporate: (888)-NBR-1EMR || fax 857.241.3022 Oh it seems to be the join that is throwing it off, because this runs in 600 ms select ac.* from application_controls_view ac where ac.application_control_id in ( 5745, 5760, 5759, 5758, 5757, 5756, 5753, 5751, 5750, 5749, 5748, 5746, 5744, 50001328, 5752, 5754, 5755, 50002757, 50002756, 50002755, 50002754, 50001168, 50020825, 50021077, 50020821, 50020822, 50020824, 50020823, 50020820, 50020819, 50020809, 50020810, 50020806, 50020807, 50020817, 50021066, 50020808 ) never mind, makes sense now - its fixed -- Gregory Caulton Principal at PatientOS Inc. personal email: caulton...@gmail.com http://www.patientos.com corporate: (888)-NBR-1EMR || fax 857.241.3022