A problem
When the program queries again, the query time is too long. Each query takes 1-2 minutes. The service feedback is that the user’s operation experience is poor
select *
FROM edi_booking edibooking0_
WHERE 1 = 1
AND edibooking0_.load_port_code IN ('CNCWN', 'CNDCB', 'AA', 'CNMWN'
, 'CWHSD', 'CNSHK', 'CNYTN', 'CNSKU')
AND edibooking0_.carrier_code = 'WHL'
AND upper(edibooking0_.so_no) LIKE upper('025%')
AND edibooking0_.load_port_code = 'CNSHK'
AND edibooking0_.status <= 1
AND edibooking0_.tfc_code = 'E19957'
ORDER BY edibooking0_.so_no ASC;
Copy the code
The query needs to be optimized
The second analysis
Upper (so_no) index upper(SO_no) upper(SO_no) index upper(SO_no) index upper(SO_no) Note that tFC_code is the same as tFC_Code, and that the database is not indexed by tFC_code. Or the TFC_Code index itself is defective, so rebuild the TFC_Code index.
alter index EDI_BOOKING_IDX_TFC_CODE rebuild online;
Copy the code
After execution, wow, the query speed is indeed up, 2s return query results. To view the execution plan, go to the tfc_code index, nice! But the story is not over yet! A day later, the service reports that the query is slow. When you check the execution plan, the index changes to upper(SO_NO). Bald on the head.
That still is a direction to think, since walked index, why return meeting slow!! The original index is not necessarily fast, this is a big mistake.
Upper (ediBooking0_.so_no) LIKE upper(‘025%’) this filter removes the index, but the index type is range_scan. Because 150W pieces of data are returned after the index is removed, and 150W pieces of data are filtered by the trailing condition, which leads to the problem of slow query.
The upper(SO_NO) index returns a lot of data, and the Oracle execution plan does not select the optimal index. If you select tFC_code, the query will be fast.
3 Solutions
-
Specifies the database selection index
Since the execution plan is automatically generated by the database, we cannot change the execution plan, but we can specify an index to make the database execute the index we specify, such as
select /*+index(edibooking0_ IDX_EDI_BOOKING_SO_TFC_CT)*/* FROM edi_booking edibooking0_ Copy the code
One drawback of this approach is that each statement executed has to be indexed, which can be a lot of modification.
-
Create composite indexes
CREATE INDEX IDX_EDI_BOOKING_SO_TFC_CT ON edi_booking (UPPER("SO_NO"), "TFC_CODE","CONTRACT_NO"); Copy the code
Composite indexes can be a bit of a pain in the backside because the query condition must be the leftmost index field to be queried, but they can be very useful, such as our current scenario, when rechecking index filtering can produce a significant performance improvement
Finally, the composite index is established to solve the problem