MySQL order by 分页查询优化

原语句特别复杂,10多个表做关联,还有子查询,执行时间13秒多。

SELECT
t.NEW_ID AS id,
t.CAR_MODE AS carMode,
t.CAR_TYPE_ID AS carTypeId,
t.VINCODE AS vinCode,
t.DERAILLEUR_TYPE AS derailleurType,
t.EXHAUST AS exhaust,
t.TONNAGE AS tonnage,
t.`LOAD` AS loadNum,
t.QUOTEDPRICE AS quotedPrice,
t.YIELDLY AS yieldly,
t.MARKET_PRICE AS marketPrice,
t.ASKER_NEW AS asker,
t.ASKER AS askerOld,
t.FILES AS files,
t.FILE_IDS AS fileIds,
t.TELEPHONE AS telephone,
t.IS_EXIGENCE AS isExigence,
t.CAR_CLASS_ID AS carClassId,
t.REQUEST_TYPE_ID AS requestTypeId,
t.CUSTOMER_ID AS customerId,
t.REQUEST_TIME AS requestTime,
t.REQUEST_STATE AS requestState,
t.FLOW_STATE AS flowState,
t.DESCRIPT AS descript,
t.REMARK AS remark,
t.PARENT_REQUEST_ID AS parentRequestId,
t.PERSON AS person,
t.OPEN_DATE AS openDate,
t.IP AS ip,
t.OLD_REQUEST_ID AS oldRequestId,
t.SECOND_FLAG AS secondFlag,
t.UN_DESC_HANDLE AS unDescHandle,
t.UN_FLAG AS unFlag,
t.REQUEST_RESOURCE AS requestResource,
t.SERVICE_GROUP_ID AS serviceGroupId,
t.DATA_TYPE AS dataType,
ct.`DESC` AS carTypeDesc,
cc.`DESC` AS carClassDesc,
u. NAME AS u_name,
u.USERNAME AS u_username,
u.COMPANY_ID AS u_companyId,
c. NAME AS c_name,
p.NEW_ID AS p_id,
p.EMPLOYEE_ID AS p_employeeId,
p.RESULT_DESC AS p_resultDesc,
p.QUERY_TIME AS p_queryTime,
p.END_TIME AS p_endTime,
p.PROCESS_TYPE AS p_processType,
p.FILE_URL AS p_fileUrl,
p.FILE_URL_NEW AS p_fileUrlNew,
p.FILE_IDS AS p_fileIds,
p.FILES AS p_files,
p.VEHICLE_MODEL AS p_vehicleModel,
p.EVALUATE AS p_evaluate,
p.NOTMY AS p_notMy,
f.NEW_ID AS f_id,
f.EMPLOYEE_NAME AS f_employeeName,
f.OPERATION_USER_ID AS f_operationUserId,
f.REMARK AS f_remark,
sv. NAME AS sv_name,
sp. NAME AS sp_name,
sf. NAME AS sf_name,
sfo. NAME AS sfo_name,
pc. NAME AS pc_name
FROM
bs_request_content t
LEFT JOIN dic_car_class cc ON cc.NEW_ID = t.CAR_CLASS_ID
LEFT JOIN dic_car_type ct ON ct.NEW_ID = t.CAR_TYPE_ID
LEFT JOIN auth_client_user u ON u.NEW_ID = t.CUSTOMER_ID
LEFT JOIN bs_company c ON c.NEW_ID = u.COMPANY_ID
LEFT JOIN bs_process p ON p.REQUEST_ID = t.NEW_ID
LEFT JOIN bs_request_forward f ON f.REQUEST_ID = t.NEW_ID
AND f.DEL_FLAG = 0
LEFT JOIN auth_server_user sp ON sp.NEW_ID = p.EMPLOYEE_ID
LEFT JOIN auth_server_user sv ON sv.NEW_ID = p.QUERY_EMPLOYEE_ID
LEFT JOIN auth_server_user sf ON sf.NEW_ID = f.EMPLOYEE_ID
LEFT JOIN auth_server_user sfo ON sfo.NEW_ID = f.OPERATION_USER_ID
LEFT JOIN bs_process_template_class pc ON pc. CODE = p.PROCESS_TYPE
WHERE
1 = 1
AND (
t.REQUEST_RESOURCE = '2'
OR EXISTS (
SELECT
'Y'
FROM
bs_request_forward y
WHERE
y.REQUEST_ID = t.NEW_ID
AND y.DEL_FLAG = '0'
AND y.SERVICE_GROUP_ID = '4028f8ba4a844758014a849540c80001'
)
)
AND NOT EXISTS (
SELECT
'N'
FROM
bs_request_forward n
WHERE
n.REQUEST_ID = t.NEW_ID
AND n.DEL_FLAG = '0'
AND n.SERVICE_GROUP_ID <> '4028f8ba4a844758014a849540c80001'
)
AND t.REQUEST_STATE = '7'
AND t.REQUEST_TIME >= concat('2017-06-01', ' 00:00:00')
AND t.REQUEST_TIME <= concat('2017-06-21', ' 23:59:59')
ORDER BY t.id DESC
LIMIT 0,30;

优化后 0.208s,执行效率提升了62.5倍,改写后的SQL如下:

SELECT
*
FROM
(
SELECT
t.id AS pkid,
t.NEW_ID AS id,
t.CAR_MODE AS carMode,
t.CAR_TYPE_ID AS carTypeId,
t.VINCODE AS vinCode,
t.DERAILLEUR_TYPE AS derailleurType,
t.EXHAUST AS exhaust,
t.TONNAGE AS tonnage,
t.`LOAD` AS loadNum,
t.QUOTEDPRICE AS quotedPrice,
t.YIELDLY AS yieldly,
t.MARKET_PRICE AS marketPrice,
t.ASKER_NEW AS asker,
t.ASKER AS askerOld,
t.FILES AS files,
t.FILE_IDS AS fileIds,
t.TELEPHONE AS telephone,
t.IS_EXIGENCE AS isExigence,
t.CAR_CLASS_ID AS carClassId,
t.REQUEST_TYPE_ID AS requestTypeId,
t.CUSTOMER_ID AS customerId,
t.REQUEST_TIME AS requestTime,
t.REQUEST_STATE AS requestState,
t.FLOW_STATE AS flowState,
t.DESCRIPT AS descript,
t.REMARK AS remark,
t.PARENT_REQUEST_ID AS parentRequestId,
t.PERSON AS person,
t.OPEN_DATE AS openDate,
t.IP AS ip,
t.OLD_REQUEST_ID AS oldRequestId,
t.SECOND_FLAG AS secondFlag,
t.UN_DESC_HANDLE AS unDescHandle,
t.UN_FLAG AS unFlag,
t.REQUEST_RESOURCE AS requestResource,
t.SERVICE_GROUP_ID AS serviceGroupId,
t.DATA_TYPE AS dataType,
ct.`DESC` AS carTypeDesc,
cc.`DESC` AS carClassDesc,
u. NAME AS u_name,
u.USERNAME AS u_username,
u.COMPANY_ID AS u_companyId,
c. NAME AS c_name,
p.NEW_ID AS p_id,
p.EMPLOYEE_ID AS p_employeeId,
p.RESULT_DESC AS p_resultDesc,
p.QUERY_TIME AS p_queryTime,
p.END_TIME AS p_endTime,
p.PROCESS_TYPE AS p_processType,
p.FILE_URL AS p_fileUrl,
p.FILE_URL_NEW AS p_fileUrlNew,
p.FILE_IDS AS p_fileIds,
p.FILES AS p_files,
p.VEHICLE_MODEL AS p_vehicleModel,
p.EVALUATE AS p_evaluate,
p.NOTMY AS p_notMy,
f.NEW_ID AS f_id,
f.EMPLOYEE_NAME AS f_employeeName,
f.OPERATION_USER_ID AS f_operationUserId,
f.REMARK AS f_remark,
sv. NAME AS sv_name,
sp. NAME AS sp_name,
sf. NAME AS sf_name,
sfo. NAME AS sfo_name,
pc. NAME AS pc_name
FROM
bs_request_content t
LEFT JOIN dic_car_class cc ON cc.NEW_ID = t.CAR_CLASS_ID
LEFT JOIN dic_car_type ct ON ct.NEW_ID = t.CAR_TYPE_ID
LEFT JOIN auth_client_user u ON u.NEW_ID = t.CUSTOMER_ID
LEFT JOIN bs_company c ON c.NEW_ID = u.COMPANY_ID
LEFT JOIN bs_process p ON p.REQUEST_ID = t.NEW_ID
LEFT JOIN bs_request_forward f ON f.REQUEST_ID = t.NEW_ID
AND f.DEL_FLAG = 0
LEFT JOIN auth_server_user sp ON sp.NEW_ID = p.EMPLOYEE_ID
LEFT JOIN auth_server_user sv ON sv.NEW_ID = p.QUERY_EMPLOYEE_ID
LEFT JOIN auth_server_user sf ON sf.NEW_ID = f.EMPLOYEE_ID
LEFT JOIN auth_server_user sfo ON sfo.NEW_ID = f.OPERATION_USER_ID
LEFT JOIN bs_process_template_class pc ON pc. CODE = p.PROCESS_TYPE
WHERE
1 = 1
AND (
t.REQUEST_RESOURCE = '2'
OR EXISTS (
SELECT
'Y'
FROM
bs_request_forward y
WHERE
y.REQUEST_ID = t.NEW_ID
AND y.DEL_FLAG = '0'
AND y.SERVICE_GROUP_ID = '4028f8ba4a844758014a849540c80001'
)
)
AND NOT EXISTS (
SELECT
'N'
FROM
bs_request_forward n
WHERE
n.REQUEST_ID = t.NEW_ID
AND n.DEL_FLAG = '0'
AND n.SERVICE_GROUP_ID <> '4028f8ba4a844758014a849540c80001'
)
AND t.REQUEST_STATE = '7'
AND t.REQUEST_TIME >= concat('2017-06-01', ' 00:00:00')
AND t.REQUEST_TIME <= concat('2017-06-21', ' 23:59:59')
) tmp_t
ORDER BY
tmp_t.pkid DESC
LIMIT 0,
 30;


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQLORDER BY语句用于对查询结果进行排序。当我们在分页查询中使用ORDER BY语句时,可能会影响查询性能,原因如下: 1. 排序操作需要消耗额外的计算资源。ORDER BY语句会对查询结果进行排序,这需要对每条记录进行比较和排序操作,消耗CPU和内存资源。 2. 排序操作可能需要使用临时表。如果查询结果集很大,MySQL可能会使用临时表来存储中间结果,然后在临时表上进行排序操作。这会增加磁盘IO操作和存储开销。 3. 排序字段的索引可能无效。如果排序的字段没有相应的索引,MySQL将无法高效地进行排序操作,而是会执行全表扫描来排序结果。全表扫描会导致查询性能下降。 为了优化分页查询中的排序操作,可以考虑以下方法: 1. 使用索引覆盖查询。如果排序字段有相应的索引,并且查询的字段只包含索引字段,MySQL可以直接使用索引进行排序,避免全表扫描和临时表的使用。 2. 限制查询结果集大小。如果只需要获取前几条记录,可以使用LIMIT子句限制结果集的大小,减少排序操作的开销。 3. 避免在分页查询中频繁改变排序字段。如果每次分页查询都使用不同的排序字段,MySQL无法充分利用缓存和索引,导致性能下降。最好在分页查询中保持相同的排序字段。 总而言之,分页查询中使用ORDER BY语句可能会影响性能,但可以通过使用索引、限制结果集大小和保持相同的排序字段等方法进行优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值