我有一个现在表现非常糟糕的SP。我在键列中有一些索引,但是SP的速度大约是14秒,可以拉出5k行,我希望它能够低于秒。我认为它与我在那里的临时表的数量有关,但是我不确定如何避免它们给出我需要访问SP中各个地方的数据。
虽然我已经设置了索引和内容,但请建议您认为可以提高性能的任何内容,我宁愿被告知做我已经做过的事情,而不是被告知重要的事情! :)
CREATE PROCEDURE [dbo].[GetPlacesByLatLong]
@minLat FLOAT,
@maxLat FLOAT,
@minLong FLOAT,
@maxLong FLOAT,
@startTime BIGINT,
@endTime BIGINT
AS
SELECT Place_routes.*
INTO #tempRoutes
FROM Place_routes
WHERE latitude BETWEEN @minLat AND @maxLat
AND longitude BETWEEN @minLong AND @maxLong
SELECT Place.*, #tempRoutes.id AS route_id
INTO #tempRoute_Places
FROM #tempRoutes
INNER JOIN link_Place_routes
ON link_Place_routes.route_id = #tempRoutes.id
INNER JOIN Place ON link_Place_routes.Place_id = Place.id
WHERE latitude BETWEEN @minLat AND @maxLat
AND longitude BETWEEN @minLong AND @maxLong
SELECT *
INTO #tempLocations
FROM locations
WHERE latitude BETWEEN @minLat AND @maxLat
AND longitude BETWEEN @minLong AND @maxLong
SELECT * INTO #tempPlaces FROM (
SELECT * FROM (
SELECT Place.*, 0 as route_id
FROM #tempLocations
INNER JOIN Place
ON #tempLocations.id = Place.location
WHERE time_start BETWEEN @startTime AND @endTime
UNION
SELECT #tempRoute_Places.* FROM #tempRoute_Places
) AS blah
UNION
SELECT * FROM (
SELECT Place.*, 0 as route_id
FROM #tempLocations
INNER JOIN Place
ON #tempLocations.id IN (SELECT #tempRoute_Places.location FROM #tempRoute_Places)
WHERE time_start BETWEEN @startTime AND @endTime
UNION
SELECT #tempRoute_Places.* FROM #tempRoute_Places
) AS blah
WHERE time_start BETWEEN @startTime AND @endTime
OR route_id <> 0
) AS blah2
ORDER BY id
SELECT * FROM #tempRoutes
SELECT * FROM #tempPlaces
UNION
SELECT external_Place_routes.Place_id, null, null, null, null, null, null, null, null, null, null, null, null, external_Place_routes.route_id, null, null FROM external_Place_routes
SELECT * FROM #tempLocations
WHERE id IN (SELECT location FROM #tempPlaces)
SELECT * FROM Place_images
WHERE Place_id in ( SELECT id FROM #tempPlaces )
ORDER BY Place_id
SELECT link_Place_types.Place_id,[types].*
FROM link_Place_types
INNER JOIN [types]
ON [types].id = link_Place_types.type_id
WHERE Place_id in ( SELECT id FROM #tempPlaces )
ORDER BY link_Place_types.Place_id
答案 0 :(得分:2)
您案例中的临时表可能对性能有所帮助。
立即弹出的三件事:
SELECT *
。尝试将选择列表缩小到您真正需要的列 - 更少的数据随机播放,然后您甚至可以创建覆盖索引。ORDER BY id
语句中删除SELECT * INTO #tempPlaces
,它没有用处并引入排序(或可能影响索引选择)对于其他任何事情我们都必须看到执行计划。
答案 1 :(得分:0)
这可能会有所帮助:
SELECT * INTO #tempPlaces FROM
在以下几个地方包含以下内容。
WHERE time_start BETWEEN @startTime AND @endTime
也许将它留在本声明末尾的位置,但将其从联合声明中删除。
SELECT * INTO #tempPlaces FROM (
SELECT * FROM (
SELECT Place.*, 0 as route_id
FROM #tempLocations
INNER JOIN Place
ON #tempLocations.id = Place.location
UNION
SELECT #tempRoute_Places.* FROM #tempRoute_Places
) AS blah
UNION
SELECT * FROM (
SELECT Place.*, 0 as route_id
FROM #tempLocations
INNER JOIN Place
ON #tempLocations.id IN (SELECT #tempRoute_Places.location FROM #tempRoute_Places)
UNION
SELECT #tempRoute_Places.* FROM #tempRoute_Places
) AS blah
WHERE time_start BETWEEN @startTime AND @endTime
OR route_id <> 0
) AS blah2