Я пытался понять, как PostgreSQL использует индексы и каковы их планы выполнения.
Я выполнил приведенный ниже запрос,
EXPLAIN(VERBOSE,ANALYZE)
SELECT SUM("Orders"."order_subtotal_net_after_discount") AS "Total sum of Order Subtotal Net After Discount"
FROM "ol"."orders_test" AS "Orders"
LEFT OUTER JOIN "ol"."ga_transactions" AS "Ga Transactions" ON "Ga Transactions"."transaction_id" = "Orders"."order_number"
WHERE ( to_char(created_at_order,'YYYY-MM-DD')=to_char(now(),'YYYY-MM-DD')
AND "Orders"."order_state_2"<>'canceled'
AND "Orders"."order_state_2" <> 'pending_payment'
AND "Orders"."order_state_1" <> 'canceled'
AND "Orders"."order_state_1" <> 'pending_payment'
AND "Orders"."order_state_1" <> 'closed'
AND "Orders"."order_state_2" <> 'closed'
)
И получил приведенный ниже план выполнения, обнаружил, что происходит последовательное сканирование с использованием фильтра ниже
Filter: ((("Orders".order_state_2)::text <> 'canceled'::text) AND (("Orders".order_state_2)::text <> 'pending_payment'::text) AND (("Orders".order_state_1)::text <> 'canceled'::text) AND (("Orders".order_state_1)::text <> 'pending_payment'::text) AND (("Orders".order_state_1)::text <> 'closed'::text) AND (("Orders".order_state_2)::text <> 'closed'::text) AND (to_char("Orders".created_at_order, 'YYYY-MM-DD'::text) = to_char(now(), 'YYYY-MM-DD'::text)))"
ЦелоеПлан запроса
Aggregate (cost=157385.36..157385.37 rows=1 width=32) (actual time=840.221..840.221 rows=1 loops=1)
Output: sum("Orders".order_subtotal_net_after_discount)
-> Nested Loop Left Join (cost=0.42..157378.56 rows=2717 width=6) (actual time=0.017..840.095 rows=470 loops=1)
Output: "Orders".order_subtotal_net_after_discount
-> Seq Scan on ol.orders_test "Orders" (cost=0.00..148623.91 rows=2717 width=16) (actual time=0.009..838.144 rows=470 loops=1)
Output: "Orders".rno, "Orders".order_id, "Orders".order_number, "Orders".invoice_id, "Orders".invoice_number, "Orders".store_id, "Orders".customer_id, "Orders".real_customer_id, "Orders".shipping_address_id, "Orders".order_state_1, "Orders".order_state_2, "Orders".invoice_state, "Orders".shipping_street, "Orders".shipping_city, "Orders".shipping_postcode, "Orders".shipping_country_id, "Orders".shipping_description, "Orders".coupon_code, "Orders".first_order_of_customer, "Orders".payment_method, "Orders".order_subtotal_net, "Orders".order_subtotal_net_after_discount, "Orders".order_subtotal, "Orders".order_shipment, "Orders".order_shipping_tax, "Orders".order_discount, "Orders".order_tax_total, "Orders".order_grand_total, "Orders".order_total_paid, "Orders".order_refunded_total, "Orders".order_total_open, "Orders".invoice_subtotal_net, "Orders".invoice_subtotal_net_after_discount, "Orders".invoice_subtotal, "Orders".invoice_shipment, "Orders".invoice_shipping_tax, "Orders".invoice_discount, "Orders".invoice_tax_total, "Orders".invoice_grand_total, "Orders".invoice_refunded_total, "Orders".created_at_order, "Orders".created_at_invoice, "Orders".updated_at_invoice, "Orders".customer_email, "Orders".row_number, "Orders".nthorder, "Orders".time_since_last_order, "Orders".time_since_first_order
Filter: ((("Orders".order_state_2)::text <> 'canceled'::text) AND (("Orders".order_state_2)::text <> 'pending_payment'::text) AND (("Orders".order_state_1)::text <> 'canceled'::text) AND (("Orders".order_state_1)::text <> 'pending_payment'::text) AND (("Orders".order_state_1)::text <> 'closed'::text) AND (("Orders".order_state_2)::text <> 'closed'::text) AND (to_char("Orders".created_at_order, 'YYYY-MM-DD'::text) = to_char(now(), 'YYYY-MM-DD'::text)))
Rows Removed by Filter: 654356
-> Index Only Scan using ga_transactions_transaction_id_idx on ol.ga_transactions "Ga Transactions" (cost=0.42..3.21 rows=1 width=10) (actual time=0.004..0.004 rows=0 loops=470)
Output: "Ga Transactions".transaction_id
Index Cond: ("Ga Transactions".transaction_id = ("Orders".order_number)::text)
Heap Fetches: 0
Planning Time: 0.540 ms
Execution Time: 840.255 ms
Я создал указанный ниже индекс, и, похоже, запрос не использует этот индекс,
Нужно ли включать все выходные столбцы вВКЛЮЧИТЬ список?
Если я добавлю больше индексов, это увеличит время обновления. Так есть ли лучший способ определить эффективные индексы для таблицы?
CREATE INDEX "IX_states"
ON ol.orders_test USING btree
(order_state_2 ASC NULLS LAST, order_state_1 ASC NULLS LAST, created_at_order ASC NULLS LAST)
INCLUDE(rno, order_id, order_number, invoice_id, invoice_number, store_id, customer_id, real_customer_id, shipping_address_id, invoice_state, shipping_street, shipping_city, shipping_postcode, shipping_country_id, shipping_description, coupon_code, first_order_of_customer, payment_method, order_subtotal_net_after_discount, created_at_invoice, customer_email, nthorder, time_since_last_order, time_since_first_order)
WITH (FILLFACTOR=90)
TABLESPACE pg_default;