STIntersects এর কর্মক্ষমতা উন্নত করা


11

সারণীতে T_PIN300,000 পিন রয়েছে এবং T_POLYGONএতে 36,000 বহুভুজ রয়েছে। T_PINএই সূচক আছে:

CREATE SPATIAL INDEX [T_PIN_COORD] ON [dbo].[T_PIN]
(
[Coord]
)USING  GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY];

T_POLYGON আছে:

CREATE SPATIAL INDEX [T_POLYGON_COORD] ON [dbo].[T_POLYGON]
(
[COORD]
)USING  GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
ON [PRIMARY];

ছেদটি খুঁজে পেতে একটি ক্যোয়ারী T_PINএবং T_POLYGONকার্যকর করতে 45 ​​মিনিটেরও বেশি সময় লাগে:

SELECT COUNT(*)
FROM T_PIN 
INNER JOIN T_POLYGON
    ON T_PIN.Coord.STIntersects(T_POLYGON.COORD) = 1;

ফলাফল 4,438,318 টি সারি।

আমি এই কোয়েরিটি কীভাবে ত্বরান্বিত করতে পারি?


আপনি কি `T_POLYGON.Coord.STIntersects (T_PIN.COORD) = 1 'ব্যবহার করে চেষ্টা করেছেন?
ট্র্যাভিস

আমি আপনার প্রশ্নের পরিকল্পনা দেখতে আগ্রহী হবে। আমি পোস্টগ্র্রেসে কাজ করি, তবে একই জাতীয় কোয়েরি চালাতে হবে, তবে উল্লেখযোগ্যভাবে বৃহত্তর ডেটা সেটগুলিতে। আমি এমন একটি কৌশল নিয়ে এসেছি যা আমার খারাপ দিকগুলি প্রায় ২ দিনের মধ্যে নামায় (যা দুর্ভাগ্যক্রমে স্ক্রিপ্টিং জড়িত), তবে আমি প্রথমে আপনার ক্যোয়ারী পরিকল্পনাটি দেখতে আগ্রহী।
জন পাওয়েল

বহুভুজগুলি আমার দুটি টেবিলের সাথে একত্রে গুণ করা, আমার সংখ্যায় আপনার সংখ্যার চেয়ে potential০০০ গুণ বেশি সম্ভাব্য ছেদগুলির সংখ্যার তুলনায়, তাই আমি মনে করি এই আলোতে আমার দুটি দিন বেশ ভাল দেখাচ্ছে। তবে কোনও ক্যোয়ারী পরিকল্পনা না দেখে এবং বহুভুতে প্রতি পয়েন্টের গড় সংখ্যার বিষয়ে কিছু না জেনে কংক্রিটের সমাধানগুলি পাওয়া শক্ত হবে।
জন পাওয়েল

উত্তর:


7

প্রথমত, ক্যোয়ারি এক্সিকিউশন প্ল্যানটি দেখে কোনও স্থানিক সূচক ব্যবহার করা হচ্ছে কিনা তা পরীক্ষা করে দেখুন এবং ক্লাস্টারড ইনডেক্স সিক (স্পেসিয়াল) আইটেম রয়েছে কিনা তা দেখুন।

এটি ব্যবহার হচ্ছে বলে ধরে নেওয়া, আপনি প্রথমে যাচাই করার জন্য সরলিকৃত বহুভুজগুলির সাথে একটি বাউন্ডিং বক্সের উপর ভিত্তি করে একটি মাধ্যমিক / সরলীকৃত ফিল্টার যুক্ত করার চেষ্টা করতে পারেন। এই সরলিকৃত বহুভুজগুলির বিরুদ্ধে ম্যাচগুলি চূড়ান্ত ফলাফল পেতে প্রাথমিক ফিল্টারটির মাধ্যমে চালানো যেতে পারে।

1) একটি নতুন ভূগোল এবং জ্যামিতি কলাম [dbo] এ যুক্ত করুন [[T_POLYGON] টেবিল:

ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeom geometry;
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog geography;

২) সীমানা বাক্স বহুভুজগুলি তৈরি করুন (এটি স্টিভেল্ফের ()) সুবিধা নিতে জ্যামিতিতে প্রাথমিক রূপান্তর জড়িত:

UPDATE [dbo].[T_POLYGON] SET SimplePolysGeom = geometry::STGeomFromWKB(
    COORD.STAsBinary(), COORD.STSrid).STEnvelope();

UPDATE [dbo].[T_POLYGON] SET SimplePolysGeog = geography::STGeomFromWKB(
    SimplePolysGeom.STAsBinary(), SimplePolysGeom.STSrid);

3) সরল ভূগোল কলামে একটি স্থানিক সূচক তৈরি করুন

4) এই সরলিকৃত ভূগোল কলামের বিপরীতে ছেদগুলি পান, তারপরে ম্যাচের ভূগোলের ডেটা টাইপগুলিতে আবার ফিল্টার করুন। মোটামুটি, এরকম কিছু:

;WITH cte AS
(
   SELECT pinID, polygonID FROM T_PIN INNER JOIN T_POLYGON
    ON T_PIN.Coord.STIntersects(T_POLYGON.SimplePolysGeog ) = 1
)
SELECT COUNT(*)
FROM T_PIN 
INNER JOIN T_POLYGON
    ON T_PIN.Coord.STIntersects(T_POLYGON.COORD) = 1
    AND T_PIN.pinID IN (SELECT pinID FROM cte)
    AND T_POLYGON.polygonID IN (SELECT polygonID FROM cte)

সম্পাদনা : আপনি (1) এবং (2) এই গণিত, স্থির কলাম দিয়ে প্রতিস্থাপন করতে পারেন। পরামর্শের জন্য পল হোয়াইটকে কৃতিত্ব।

ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS  ([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),[COORD].[STSrid]).STEnvelope().STAsBinary(),(4326))) PERSISTED

হ্যাঁ, আমি যা পেয়েছিলাম তা কমবেশি এটি। বিস্তৃত কভারেজের অঞ্চল সহ দুটি সেট টেবিলের স্থানিকভাবে "যোগদান" করার সময় আমি যে বিষয়টি খুঁজে পেয়েছি তা হ'ল অপটিমাইজার প্রায়শই দুটি পূর্ণ টেবিল স্ক্যান এবং বহুভুজ পরীক্ষায় পয়েন্ট লোড করার জন্য যায়।
জন পাওয়েল

2

বহুভুজগুলির জটিলতার কারণে এ জাতীয় প্রশ্নগুলি প্রায়শই দীর্ঘ সময় নেয়। আমি জটিল উপকূলরেখাগুলি দেখেছি (উদাহরণস্বরূপ) তাদের সীমানার কাছাকাছি অবস্থিত পয়েন্টগুলি পরীক্ষা করতে যুগে যুগে সময় লাগে, পয়েন্টটি ভিতরে বা বাইরে রয়েছে কিনা তা খুঁজে পেতে অনেকগুলি স্তর জুম করতে হবে।

... যাতে আপনি .Reduce()বহুভুজগুলিকে অন্তর্ভুক্ত করার চেষ্টা করতে পারেন, এটি কিনা সহায়তা করে কিনা তা দেখার জন্য।

এবং এই ফাংশন সম্পর্কে আরও তথ্যের জন্য, http://msdn.microsoft.com/en-us/library/cc627410.aspx দেখুন


1

মাইক্রোসফ্ট ডক্স অনুসারে, স্পেসিয়াল ইনডেক্সগুলি যখন কোনও WHEREঅনুচ্ছেদের সাথে প্রোটিকেট তুলনা শুরুর দিকে উপস্থিত হবে তখন নিম্নলিখিত পদ্ধতিগুলিতে ভূগোলের ধরণের সাথে ব্যবহার করা হবে :

  • STIntersects
  • STDistance
  • STEquals

কেবল জ্যামিতির ধরণের পদ্ধতির (সীমাবদ্ধ তালিকা) স্থানিক সূচীর ব্যবহারকে ট্রিগার করবে JOIN ... ON, সুতরাং আপনার কোডটি ব্যবহারের জন্য পরিবর্তন করুন WHERE geog1.STIntersects(geog2) = 1এবং এটির গতি উন্নত করা উচিত।

আমি g2server এর উত্তরে পরামর্শ নেওয়ার এবং ফিল্টারিংয়ের জন্য নিম্নলিখিতগুলি যুক্ত করতে এবং এটিতে স্থানিক সূচক যুক্ত করার পরামর্শ দিই

ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
     ([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
                                                           [COORD].[STSrid])
                 .STEnvelope().STAsBinary(),(4326))) PERSISTED

আপনার নীচের মত একটি প্রশ্ন থাকতে পারে (আমি এই পোস্টটি দ্রুত লিখেছিলাম এবং এখনও পরীক্ষা করে দেখিনি, এটি চেষ্টা করার মতো কিছু কারণ আমি দেখেছি যে আপনার ক্যোয়ারী এবং সর্বাধিক পোস্ট করা উত্তরগুলি স্থানিক ওপ = 1 ব্যবহার করবে যা কোনও ব্যবহার করবে না স্থানিক সূচক):

SELECT   
     (SELECT p2.polygon_id
      FROM   T_Polygon p2
      WHERE  p2.coords.STIntersects(t.coords) = 1),
     t.pin_id
FROM     T_PIN t
WHERE    
     (SELECT t.coords.STIntersects(p.coords)
      FROM   T_POLYGON p
      WHERE  t.coords.STIntersects(p.SimplePolysGeog) = 1) = 1

এফওয়াইআই: SimplePolysGeogওভারল্যাপিং শেষ না হলে উপরেরগুলি কাজ করে না (একটি পিনের মতো দুটি সরল ভূগোলের মধ্যে থাকতে পারে, এটি কেবল একটি রাজ্যের সীমান্তে লোকের উপর দৌড়ে এবং যেহেতু সাধারণ পলিসি সীমানা ভাগ করে দেয়, সীমাবদ্ধ বাক্সগুলি ওভারল্যাপ করে) তাই বেশিরভাগ ব্যবহারে কেসগুলি, এটি এমন একটি ত্রুটি ছুঁড়ে দেবে যা subquery একাধিক ফলাফল প্রত্যাবর্তন করেছে।

এমএস ডক্সের স্পেশাল ইনডেক্সগুলি ওভারভিউ থেকে :

ভূগোল পদ্ধতি স্থানীয় সূচকগুলি দ্বারা সমর্থিত

কিছু শর্তের মধ্যে, স্থানিক সূচকগুলি নিম্নলিখিত সেট-ভিত্তিক ভূগোল পদ্ধতিগুলি সমর্থন করে: STIntersects (), STEquals (), এবং STDistance ()। একটি স্থানিক সূচক দ্বারা সমর্থিত হওয়ার জন্য, এই পদ্ধতিগুলি অবশ্যই কোনও প্রশ্নের কোনও ক্লজের মধ্যে ব্যবহার করা উচিত এবং সেগুলি অবশ্যই নিম্নলিখিত সাধারণ ফর্মের একটি প্রাকটিকের মধ্যে উপস্থিত হতে হবে:

geography1.method_name (geography2) comparison_operatorvalid_number

একটি নন-ফলাফল বাতিল করতে, ভূগোল 1 এবং ভূগোল 2 এর অবশ্যই একই স্থানিক রেফারেন্স আইডেন্টিফায়ার (এসআরআইডি) থাকতে হবে । অন্যথায়, পদ্ধতিটি NULL প্রদান করে।

স্থানিক সূচকগুলি নিম্নলিখিত ভবিষ্যদ্বাণীপূর্ণ ফর্মগুলি সমর্থন করে:


স্থানিক সূচকগুলি ব্যবহার করে এমন প্রশ্নগুলি

স্পেসিয়াল ইনডেক্সগুলি কেবলমাত্র কোয়েরিতে সমর্থিত হয় যেখানে WHERE ধারাটিতে একটি সূচকযুক্ত স্থানিক অপারেটর অন্তর্ভুক্ত থাকে। উদাহরণস্বরূপ সিনট্যাক্স যেমন:

[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]

ক্যোয়ারী অপ্টিমাইজার স্থানিক ক্রিয়াকলাপ (যে @a.STIntersects(@b) = @b.STInterestcs(@a)) এর পরিবহণকে বোঝে । তবে, তুলনা শুরুর ক্ষেত্রে স্থানিক অপারেটর WHERE 1 = spatial opনা থাকলে স্থানিক সূচক ব্যবহার করা হবে না (উদাহরণস্বরূপ স্পেসিয়াল ইনডেক্স ব্যবহার করবে না)। স্থানিক সূচকটি ব্যবহার করতে, তুলনাটি পুনরায় লিখুন (উদাহরণস্বরূপ WHERE spatial op = 1)।

...

SimplePolysGeogsওভারল্যাপ হলে নিম্নলিখিত কোয়েরিটি কাজ করবে :

;WITH cte AS
(
   SELECT T_PIN.PIN_ID, 
          T_POLYGON.POLYGON_ID, 
          T_POLYGON.COORD 
   FROM T_PIN 
   INNER JOIN T_POLYGON
   ON T_PIN.COORD.STIntersects(T_POLYGON.SimplePolysGeog) = 1
)

SELECT COUNT(*)
FROM T_PIN 
INNER JOIN cte
ON T_PIN_PIN_ID = cte.PIN_ID
where cte.[COORD].STIntersects(T_PIN.COORD) = 1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.