【发布时间】:2018-02-02 19:23:54
【问题描述】:
我在处理数据库中的一个非常大的表时遇到了一些麻烦。在说问题之前,先说一下我想要达到的目标。
我有两个源表:
- 来源 1:
SALES_MAN (ID_SMAN, SM_LATITUDE, SM_LONGITUDE) 来源 2:
CLIENT (ID_CLIENT, CLATITUDE, CLONGITUDE)目标:
DISTANCE (ID_SMAN, ID_CLIENT, SM_LATITUDE, SM_LONGITUDE, CLATITUDE, CLONGITUDE, DISTANCE)
这个想法是在目标表中使用ROW_NUMBER 为每个客户端找到最接近SALES_MAN 的前N 个。
我目前正在做的是计算每个客户和每个销售人员之间的距离:
INSERT INTO DISTANCE ([ID_SMAN], [ID_CLIENT], [DISTANCE],
[SM_LATITUDE], [SM_LONGITUDE], [CLATITUDE], [CLONGITUDE])
SELECT
[ID_SMAN], [ID_CLIENT],
geography::STGeomFromText('POINT('+IND_LATITUDE+' '+IND_LONGITUDE+')',4326).STDistance(geography::STGeomFromText('POINT('+DLR.[DLR_N_GPS_LATTITUDE]+' '+DLR.[DLR_N_GPS_LONGITUDE]+')',4326))/1000 as distance,
[SM_LATITUDE], [SM_LONGITUDE], [CLATITUDE], [CLONGITUDE]
FROM
[dbo].[SALES_MAN], [dbo].[CLIENT]
DISTANCE 表包含大约 1 兆行。
让每个客户离我最近的 5 个销售人员的第二步是运行以下查询:
SELECT *
FROM
(SELECT
*,
ROW_NUMBER() OVER(PARTITION BY ID_CLIENT ORDER BY DISTANCE) rang
FROM DISTANCE) TAB
WHERE rang < 6
最后一个查询确实是一个消耗性的查询。因此,为了避免 SORT 运算符,我尝试在 DISTANCE 和 ID_CLIENT 中创建一个排序的非聚集索引,但它不起作用。我还尝试在两个索引中包含所有需要的列。
但是当我在DISTANCE 上创建一个聚集索引并将非聚集排序索引保留在ID_CLIENT 中时,事情变得更好了。
那么在这种情况下,什么非聚集排序索引不起作用?
但是当我使用聚集索引时,我在加载数据时遇到了其他问题,我不得不在开始加载过程之前将其删除。
那你怎么看?以及我们如何处理这种表以便能够选择、插入或更新数据而不会出现性能问题?
非常感谢
【问题讨论】:
-
Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI
JOIN语法-92 SQL 标准(25 年前),不鼓励使用它
标签: sql-server performance sql-server-2016 clustered-index non-clustered-index