如何减少mysql查询运行时间
这是我在网站的一个页面上运行的查询如何减少mysql查询运行时间,mysql,Mysql,这是我在网站的一个页面上运行的查询 SELECT DISTINCT b.CruisePortID, b.SailingDates, b.CruisePortID, b.ArriveTime, b.DepartTime, b.PortName, b.DayNumber FROM cruise_itineraries a, cruise_itinerary_days b, cruise_ports c WHERE a.
SELECT
DISTINCT b.CruisePortID,
b.SailingDates,
b.CruisePortID,
b.ArriveTime,
b.DepartTime,
b.PortName,
b.DayNumber
FROM
cruise_itineraries a,
cruise_itinerary_days b,
cruise_ports c
WHERE
a.ID = b.CruiseItineraryID
AND a.CruisePortID = c.ID
AND a.ID = '352905'
AND b.CruisePortID != 0
GROUP BY b.DayNumber;
在phpmy admin中运行此查询需要3.20秒,因为巡航计划有30多万条记录
我也尝试了索引,索引后显示2.92秒。是否有可能将查询时间缩短到0.10秒以下。这有助于提高我的网站性能
这里是详细信息
CREATE TABLE IF NOT EXISTS `cruise_itineraries` (
`cl` int(11) NOT NULL,
`ID` bigint(20) NOT NULL,
`Description` varchar(500) NOT NULL,
`SailingPlanID` varchar(100) NOT NULL,
`VendorID` varchar(100) NOT NULL,
`VendorName` varchar(100) NOT NULL,
`ShipID` varchar(100) NOT NULL,
`ShipName` varchar(100) NOT NULL,
`Duration` int(11) NOT NULL,
`DestinationID` varchar(100) NOT NULL,
`Date` datetime NOT NULL,
`CruisePortID` varchar(100) NOT NULL,
`TradeRestriction` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `cruise_itinerary_days` (
`cld` int(11) NOT NULL,
`CruiseItineraryID` varchar(100) NOT NULL,
`SailingDates` datetime NOT NULL,
`VendorID` int(11) NOT NULL,
`VendorName` varchar(100) NOT NULL,
`ShipID` int(11) NOT NULL,
`ShipName` varchar(100) NOT NULL,
`SailingPlanID` int(11) NOT NULL,
`PlanName` varchar(100) NOT NULL,
`DayNumber` bigint(20) NOT NULL,
`PortName` varchar(100) NOT NULL,
`CruisePortID` varchar(100) NOT NULL,
`ArriveTime` varchar(100) NOT NULL,
`DepartTime` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `cruise_ports` (
`cp` int(11) NOT NULL,
`ID` varchar(100) NOT NULL,
`Name` varchar(100) NOT NULL,
`Description` varchar(1000) NOT NULL,
`NearestAirportCode` varchar(100) NOT NULL,
`UNCode` varchar(100) NOT NULL,
`Address` varchar(500) NOT NULL,
`City` varchar(100) NOT NULL,
`StateCode` varchar(100) NOT NULL,
`CountryCode` varchar(100) NOT NULL,
`PostalCode` varchar(100) NOT NULL,
`Phone` varchar(50) NOT NULL,
`Fax` varchar(100) NOT NULL,
`Directions` varchar(1000) NOT NULL,
`Content` varchar(1000) NOT NULL,
`HomePageURL` varchar(100) NOT NULL,
`Longitude` varchar(100) NOT NULL,
`Latitude` varchar(500) NOT NULL,
`CarnivalID` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `cruise_itineraries`
ADD PRIMARY KEY (`cl`),
ADD KEY `ID_2` (`ID`);
ALTER TABLE `cruise_itineraries`
ADD PRIMARY KEY (`cl`),
ADD KEY `ID_2` (`ID`);
ALTER TABLE `cruise_itinerary_days`
ADD PRIMARY KEY (`cld`);
ALTER TABLE `cruise_ports`
ADD PRIMARY KEY (`cp`);
ALTER TABLE `cruise_itineraries`
MODIFY `cl` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `cruise_itinerary_days`
MODIFY `cld` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `cruise_ports`
MODIFY `cp` int(11) NOT NULL AUTO_INCREMENT;
解释结果:
+----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------------------------------------+
| 1 | SIMPLE | a | ref | ID_2 | ID_2 | 8 | const | 1 | Using index condition; Using temporary; Using filesort |
| 1 | SIMPLE | c | ALL | NULL | NULL | NULL | NULL | 3267 | Using where; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | b | ALL | NULL | NULL | NULL | NULL | 2008191 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------------------------------------+
+----+-------------+-------+------+------------------------------------+------------------------------------+---------+-------+------+--------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+------------------------------------+------------------------------------+---------+-------+------+--------------------------------------------------------------+
| 1 | SIMPLE | b | ref | Idx_CruiseItineraryID_CruisePortID | Idx_CruiseItineraryID_CruisePortID | 9 | const | 12 | Using index condition; Using temporary; Using filesort |
| 1 | SIMPLE | a | ref | ID_2 | ID_2 | 8 | const | 1 | Distinct |
| 1 | SIMPLE | c | ALL | NULL | NULL | NULL | NULL | 3267 | Using where; Distinct; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+------------------------------------+------------------------------------+---------+-------+------+--------------------------------------------------------------+
首先,我想声明,尽量避免隐式MySQL连接。 改为使用内部联接 我个人认为内部连接更好,因为它更简单 可读的。它更好地显示了表格之间的关系。你有 连接中的这些关系,并在何处进行过滤 条款这种分离使查询更具可读性 我发现的缺点是:
- 邮轮行程.ID的数据类型为BIGINT,而邮轮行程.cruiseIneraryid的数据类型为varchar。但您在查询中匹配了它们。因此,无论您在巡航行程天数上使用索引,它都会运行缓慢
将cruise\u Tinerary\u days.CruiseIneraryId的数据类型更改为BIGINT
ALTER TABLE cruise\u internative\u days修改cruiseIneraryID BIGINT代码>
- 接下来,您必须根据查询在cruise\u Cinerary\u days表上创建一个复合索引
(ALTER TABLE cruise\u international\u days添加索引Idx\u cruiseIneraryID\u CruisePortID
,cruiseIneraryID
)`CruisePortID
- 现在在cruise_ports.ID字段的cruise_ports表中创建索引
更改表格
添加索引cruise\u port
(Idx\u cruise\u port\u ID
)ID
SELECT
DISTINCT b.CruisePortID,
b.SailingDates,
b.CruisePortID,
b.ArriveTime,
b.DepartTime,
b.PortName,
b.DayNumber
FROM cruise_itineraries a
INNER JOIN cruise_itinerary_days b ON a.ID = b.CruiseItineraryID
INNER JOIN cruise_ports c ON a.CruisePortID = c.ID
WHERE a.ID = 352905
AND b.CruisePortID != 0
GROUP BY b.DayNumber;
发布所有相关的表结构。我的意思是创建表代码。意思是您想要这些表的数据结构,对吗?还要说明您在tablescreate表语句中有哪些索引示例:
create table MyGuests(id INT(6)无符号自动递增主键,firstname VARCHAR(30)不为NULL,lastname VARCHAR(30)不为NULL,email VARCHAR(50),regu date TIMESTAMP)
正如您所看到的,cruise\u Tinerary\u days表中的扫描行数非常多!!谢谢你的建议。我将实现并与您共享结果。请共享此查询的解释结果。听起来很棒@vigneshrajkumarcruise\u ports
needsINDEX(ID)
。如果答案适合您,请练习将其标记为已接受。让别人觉得它有用@维涅斯拉伊库马尔