请帮帮我,解决这个缓慢的查询
表格:
CREATE TABLE `products` (
`ProductId` int(11) NOT NULL AUTO_INCREMENT,
`CategoryId` int(11) NOT NULL,
`BrandId` int(11) DEFAULT NULL,
`PCode` varchar(100) COLLATE utf8_persian_ci NOT NULL,
`PName` varchar(255) COLLATE utf8_persian_ci NOT NULL,
`UnitId` int(11) DEFAULT NULL,
`PNameEn` varchar(250) COLLATE utf8_persian_ci DEFAULT NULL,
`PShortName` varchar(100) COLLATE utf8_persian_ci DEFAULT NULL,
`PDescription` varchar(250) COLLATE utf8_persian_ci DEFAULT NULL,
`Weight` int(11) DEFAULT NULL,
`PImage` varchar(100) COLLATE utf8_persian_ci NOT NULL DEFAULT 'noimage.png',
`PIcon` varchar(100) COLLATE utf8_persian_ci DEFAULT 'noicon.png',
`PGallery` varchar(250) COLLATE utf8_persian_ci DEFAULT NULL,
`PDetail` text COLLATE utf8_persian_ci,
`PTags` text COLLATE utf8_persian_ci,
`PSpecial` tinyint(4) NOT NULL DEFAULT '0',
`PView` int(11) NOT NULL DEFAULT '0',
`Status` tinyint(2) DEFAULT '1' COMMENT '0: inactive. 1: active. 5: deleted.',
`BasePrice` int(11) DEFAULT NULL,
`PCreateDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`PUpdateDate` datetime NOT NULL,
`PUrl` varchar(255) COLLATE utf8_persian_ci DEFAULT NULL,
`ProviderName` varchar(255) COLLATE utf8_persian_ci DEFAULT NULL,
PRIMARY KEY (`ProductId`),
UNIQUE KEY `PCode` (`PCode`),
KEY `CategoryId` (`CategoryId`),
KEY `BrandId` (`BrandId`),
KEY `PName` (`PName`)
) ENGINE=MyISAM AUTO_INCREMENT=341028 DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci
CREATE TABLE `units` (
`UnitId` int(11) NOT NULL AUTO_INCREMENT,
`UnitName` varchar(25) COLLATE utf8_persian_ci NOT NULL,
PRIMARY KEY (`UnitId`)
) ENGINE=MyISAM AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci
CREATE TABLE `products_sub` (
`ProductSubId` int(11) NOT NULL AUTO_INCREMENT,
`ProviderId` int(11) NOT NULL,
`PCode` varchar(100) COLLATE utf8_persian_ci NOT NULL,
`Price` int(11) NOT NULL,
`ProviderPrice` int(11) NOT NULL,
`PQuantity` int(10) NOT NULL,
`PDeliveryTime` time NOT NULL,
`PEditTime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`ProductSubId`),
KEY `ProviderId` (`ProviderId`),
KEY `PCode` (`PCode`)
) ENGINE=MyISAM AUTO_INCREMENT=340349 DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci
CREATE TABLE `provider` (
`ProviderId` int(11) NOT NULL AUTO_INCREMENT,
`UserId` int(11) NOT NULL,
`ProviderName` varchar(25) COLLATE utf8_persian_ci NOT NULL,
`ProviderPhone` varchar(11) COLLATE utf8_persian_ci NOT NULL,
`ProviderCell` varchar(11) COLLATE utf8_persian_ci NOT NULL,
`ProviderAddress` varchar(250) COLLATE utf8_persian_ci NOT NULL,
`ProviderDetail` text COLLATE utf8_persian_ci NOT NULL,
`Email` varchar(50) COLLATE utf8_persian_ci NOT NULL,
`Status` tinyint(1) NOT NULL,
`RequestTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Permission` varchar(250) COLLATE utf8_persian_ci NOT NULL,
PRIMARY KEY (`ProviderId`),
UNIQUE KEY `UserId` (`UserId`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci
CREATE TABLE `order_products` (
`OrderProductId` int(11) NOT NULL AUTO_INCREMENT,
`OrderId` int(11) NOT NULL,
`ProviderId` int(11) NOT NULL,
`PCode` varchar(50) COLLATE utf8_persian_ci NOT NULL,
`PName` varchar(50) COLLATE utf8_persian_ci NOT NULL,
`PUnit` varchar(50) COLLATE utf8_persian_ci NOT NULL,
`Token` int(11) NOT NULL DEFAULT '999',
`ProductPrice` int(11) NOT NULL,
`ProductWeight` int(11) NOT NULL,
`ProductPurchase` int(11) NOT NULL,
PRIMARY KEY (`OrderProductId`),
KEY `ProductId` (`PCode`),
KEY `OrderId` (`OrderId`),
KEY `ProviderId` (`ProviderId`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci
CREATE TABLE `brands` (
`BrandId` int(11) NOT NULL AUTO_INCREMENT,
`BrandName` varchar(25) NOT NULL,
`BrandEn` varchar(25) DEFAULT NULL,
PRIMARY KEY (`BrandId`),
UNIQUE KEY `BrandName` (`BrandName`)
) ENGINE=MyISAM AUTO_INCREMENT=1988 DEFAULT CHARSET=utf8
我的查询
SELECT
`products`.`ProductId`,
`products`.`PName`,
`products`.`Status`,
`products`.`PSpecial`,
`products`.`PImage`,
`products`.`BasePrice`,
`products`.`CategoryId`,
`units`.`UnitName`,
`products_sub`.`ProductSubId`,
`products_sub`.`ProviderId`,
`products_sub`.`PQuantity`,
`products_sub`.`ProviderPrice`,
`products_sub`.`Price` AS `customerPrice`,
`provider`.`ProviderName`,
SUM(`order_products`.`ProductPurchase`) AS `sale`
FROM
`products`
LEFT JOIN
`brands`
ON
`products`.`BrandId`=`brands`.`BrandId`
INNER JOIN
`units`
ON
`products`.`UnitId`=`units`.`UnitId`
LEFT JOIN
`products_sub`
ON
`products`.`PCode`=`products_sub`.`PCode`
AND
`products_sub`.`ProductSubId` =
(
SELECT
`ProductSubId`
FROM
`products_sub`
WHERE
`PCode`=`products`.`PCode`
AND
`PQuantity` > 0
ORDER BY
`ProviderPrice`
LIMIT
1
)
LEFT JOIN
`provider`
ON
`products_sub`.`ProviderId`=`provider`.`ProviderId`
LEFT JOIN
`order_products`
ON
`products`.`PCode`=`order_products`.`PCode`
WHERE
`products`.`Status`>0
AND
`products`.`Status`!=5
AND
`products`.`CategoryId` IN (1133,1134,1137,1174,1175,1176,1138,1177,1178,1179,1139,1140,1141,1180,1181,1182,1183,1184,1142,1143,1144,1145,1185,1186,1187,1188,1189,1190,1191,1146,1147,1148,1149,1150,1192,1193,1194,1855,1856,1857,1135,1151,1152,1153,1154,1155,1156,1157,1158,1136,1159,1160,1161,1162,1163,1164,1165,1166,1195,1196,1197,1198,1199,1167,1168,1200,1201,1202,1203,1204,1205,1169,1206,1207,1208,1209,1170,1171,1172,1173,1210,1211,1858,1859,1212,1213,1214,1232,1233,1234,1215,1216,1235,1236,1237,1238,1217,1239,1240,1241,1242,1218,1219,1220,1243,1244,1245,1246,1247,1248,1221,1249,1250,1251,1222,1223,1224,1252,1253,1254,1225,1255,1256,1257,1258,1259,1260,1261,1262,1263,1226,1227,1228,1229,1230,1231,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1463,1464,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1465,1466,1467,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1468,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1469,1470,1471,1472,1473,1474,1508,1509,1286,1287,1290,1299,1395,1396,1300,1301,1397,1398,1399,1302,1303,1304,1305,1400,1401,1402,1306,1307,1308,1309,1403,1404,1310,1405,1406,1407,1408,1311,1312,1313,1314,1315,1409,1410,1291,1316,1317,1318,1319,1320,1292,1321,1322,1323,1324,1288,1293,1325,1411,1412,1326,1327,1413,1414,1328,1329,1330,1331,1415,1416,1417,1418,1332,1419,1420,1421,1422,1333,1334,1335,1423,1424,1336,1425,1426,1427,1428,1429,1430,1431,1337,1338,1432,1433,1434,1339,1340,1341,1342,1435,1436,1437,1343,1438,1439,1440,1441,1294,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1295,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1860,1861,1862,1289,1296,1364,1442,1443,1444,1365,1445,1446,1447,1448,1366,1367,1368,1369,1449,1450,1451,1452,1453,1370,1371,1372,1373,1454,1455,1456,1457,1458,1459,1374,1375,1460,1376,1377,1378,1379,1461,1462,1297,1380,1381,1382,1383,1384,1385,1386,1298,1387,1388,1389,1390,1391,1392,1393,1394,1863,1864,1865,1132)
GROUP BY
`products`.`PCode`
ORDER BY
`products`.`Status`,
`products_sub`.`PQuantity` > 0 DESC,
`products`.`PSpecial` DESC,
`customerPrice` ASC,
`products`.`BasePrice` ASC
LIMIT
36
OFFSET
0
此查询非常慢:(
当删除ORDER BY部分时,它将运行非常快。
根据我的研究,最好使用子查询。但没有弄清楚如何在左联接中使用它们。
感谢您的帮助。谢谢。
答案 0 :(得分:0)
FWIW,我将以这种方式编写该查询。我不能说它将对性能产生任何显着影响,但是如果您提供相同的EXPLAIN,那么我们可以着眼于改善索引...
SELECT p.productid
, p.pname
, p.status
, p.pspecial
, p.pimage
, p.baseprice
, p.categoryid
, u.unitname
, s.productsubid
, s.providerid
, s.pquantity
, s.providerprice
, s.price customerprice
, r.providername
, SUM(op.productpurchase) sale
FROM products p
JOIN units u
ON u.unitid = p.unitid
LEFT
JOIN products_sub s
ON s.pcode = p.pcode
JOIN
( SELECT productsubid
, pcode
, MIN(providerprice) providerprice
FROM products_sub
WHERE pquantity = 0
GROUP
BY productsubid
, pcode
) x
ON x.productsubid = s.productsubid
AND x.pcode = p.pcode
AND x.providerprice = s.provideprice
LEFT
JOIN provider r
ON r.providerid = s.providerid
LEFT
JOIN order_products op
ON op.pcode = p.pcode
WHERE p.status > 0
AND p.status != 5
AND p.categoryid in
( 1133 , 1134 , 1137 , 1174 , 1175 , 1176 , 1138 , 1177 , 1178 , 1179 , 1139 , 1140 , 1141 , 1180 , 1181 , 1182 , 1183 , 1184 , 1142 , 1143
, 1144 , 1145 , 1185 , 1186 , 1187 , 1188 , 1189 , 1190 , 1191 , 1146 , 1147 , 1148 , 1149 , 1150 , 1192 , 1193 , 1194 , 1855 , 1856 , 1857
, 1135 , 1151 , 1152 , 1153 , 1154 , 1155 , 1156 , 1157 , 1158 , 1136 , 1159 , 1160 , 1161 , 1162 , 1163 , 1164 , 1165 , 1166 , 1195 , 1196
, 1197 , 1198 , 1199 , 1167 , 1168 , 1200 , 1201 , 1202 , 1203 , 1204 , 1205 , 1169 , 1206 , 1207 , 1208 , 1209 , 1170 , 1171 , 1172 , 1173
, 1210 , 1211 , 1858 , 1859 , 1212 , 1213 , 1214 , 1232 , 1233 , 1234 , 1215 , 1216 , 1235 , 1236 , 1237 , 1238 , 1217 , 1239 , 1240 , 1241
, 1242 , 1218 , 1219 , 1220 , 1243 , 1244 , 1245 , 1246 , 1247 , 1248 , 1221 , 1249 , 1250 , 1251 , 1222 , 1223 , 1224 , 1252 , 1253 , 1254
, 1225 , 1255 , 1256 , 1257 , 1258 , 1259 , 1260 , 1261 , 1262 , 1263 , 1226 , 1227 , 1228 , 1229 , 1230 , 1231 , 1264 , 1265 , 1266 , 1267
, 1268 , 1269 , 1270 , 1271 , 1272 , 1273 , 1274 , 1275 , 1276 , 1277 , 1278 , 1279 , 1280 , 1281 , 1282 , 1283 , 1284 , 1285 , 1463 , 1464
, 1475 , 1476 , 1477 , 1478 , 1479 , 1480 , 1481 , 1482 , 1483 , 1484 , 1465 , 1466 , 1467 , 1485 , 1486 , 1487 , 1488 , 1489 , 1490 , 1491
, 1492 , 1493 , 1494 , 1468 , 1495 , 1496 , 1497 , 1498 , 1499 , 1500 , 1501 , 1502 , 1503 , 1504 , 1505 , 1506 , 1507 , 1469 , 1470 , 1471
, 1472 , 1473 , 1474 , 1508 , 1509 , 1286 , 1287 , 1290 , 1299 , 1395 , 1396 , 1300 , 1301 , 1397 , 1398 , 1399 , 1302 , 1303 , 1304 , 1305
, 1400 , 1401 , 1402 , 1306 , 1307 , 1308 , 1309 , 1403 , 1404 , 1310 , 1405 , 1406 , 1407 , 1408 , 1311 , 1312 , 1313 , 1314 , 1315 , 1409
, 1410 , 1291 , 1316 , 1317 , 1318 , 1319 , 1320 , 1292 , 1321 , 1322 , 1323 , 1324 , 1288 , 1293 , 1325 , 1411 , 1412 , 1326 , 1327 , 1413
, 1414 , 1328 , 1329 , 1330 , 1331 , 1415 , 1416 , 1417 , 1418 , 1332 , 1419 , 1420 , 1421 , 1422 , 1333 , 1334 , 1335 , 1423 , 1424 , 1336
, 1425 , 1426 , 1427 , 1428 , 1429 , 1430 , 1431 , 1337 , 1338 , 1432 , 1433 , 1434 , 1339 , 1340 , 1341 , 1342 , 1435 , 1436 , 1437 , 1343
, 1438 , 1439 , 1440 , 1441 , 1294 , 1344 , 1345 , 1346 , 1347 , 1348 , 1349 , 1350 , 1351 , 1352 , 1353 , 1295 , 1354 , 1355 , 1356 , 1357
, 1358 , 1359 , 1360 , 1361 , 1362 , 1363 , 1860 , 1861 , 1862 , 1289 , 1296 , 1364 , 1442 , 1443 , 1444 , 1365 , 1445 , 1446 , 1447 , 1448
, 1366 , 1367 , 1368 , 1369 , 1449 , 1450 , 1451 , 1452 , 1453 , 1370 , 1371 , 1372 , 1373 , 1454 , 1455 , 1456 , 1457 , 1458 , 1459 , 1374
, 1375 , 1460 , 1376 , 1377 , 1378 , 1379 , 1461 , 1462 , 1297 , 1380 , 1381 , 1382 , 1383 , 1384 , 1385 , 1386 , 1298 , 1387 , 1388 , 1389
, 1390 , 1391 , 1392 , 1393 , 1394 , 1863 , 1864 , 1865 , 1132
)
GROUP
BY p.productid
, p.pname
, p.status
, p.pspecial
, p.pimage
, p.baseprice
, p.categoryid
, u.unitname
, s.productsubid
, s.providerid
, s.pquantity
, s.providerprice
, s.price
, r.providername
ORDER
BY p.status
, s.pquantity > 0 desc
, p.pspecial desc
, customerpprice asc
, p.baseprice asc
LIMIT 36
OFFSET 0
答案 1 :(得分:0)
这将大大加快一个子查询的速度:INDEX(PCode, PQuantity, ProviderPrice)
。添加时,您也可以摆脱KEY PCode (PCode)
从MyISAM切换到InnoDB。
基于对status
的评论
`products`.`Status`>0
AND `products`.`Status`!=5
可以简单地变成products.Status = 1
。这样做的原因是使某些优化成为可能。特别是,这将变得有用:
INDEX(Status, CategoryId)