পোস্টজিআইএস দূরত্বের প্রশ্নের জন্য সূচকগুলি কীভাবে সঠিকভাবে সেট আপ করবেন?


18

আমি এমন একটি অ্যাপ্লিকেশন তৈরি করছি Recordযা Xকিলোমিটার দূরে থাকা টেবিলটিতে প্রতিটি জিজ্ঞাসা এবং ফিরে আসার কথা PointXRecordsএবং PointXএর অবস্থানগুলি (long/lat)গুগল জিওকোড এপিআই দ্বারা সরবরাহিত তথ্য থেকে নির্ধারিত হয় ।

আমি পোস্টজিআইএসে নতুন দ্রুত গবেষণার পরে, আমি এই প্রশ্নটি পেয়েছি । উত্তরটি এই লাইনের সাথে রয়েছে বলে মনে হচ্ছে:

SELECT *
FROM your_table
WHERE ST_Distance_Sphere(the_geom, ST_MakePoint(your_lon,your_lat)) <= radius_mi * 1609.34

সমস্যাটি হ'ল: যদিও আমি কেবল জিআইএস-এ শুরু করছি, যখন আমি উপরের ক্যোয়ারীর দিকে নজর রাখি, আমি সম্ভবত এটি কল্পনা করতে পারি না যে এটি কীভাবে একটি সূচক ব্যবহার করতে পারে। এখানে 2 টি ফাংশন কল রয়েছে। আমি কল্পনা করি যে টেবিলটি প্রতিটি জন্য স্ক্যান করা হচ্ছে Record। আমি ভুল হতে চাই :)

প্রশ্ন: পোস্টজিআইএসের উপরের ক্যোয়ারী পারফর্ম্যান্ট তৈরি করতে সক্ষম কোনও সূচক প্রকার আছে কি? যদি তা না হয় তবে আমার যা প্রয়োজন তা করার প্রস্তাবিত পদ্ধতির কী হবে?


আপনার কাছে সঠিক সূচক সংগ্রহ করতে, ভূগোল করার জন্য একটি ঢালাই উপর, এবং একটি আবেদন করুন ST_SetSRID()থেকে ST_MakePointক্যোয়ারীতে ভূগোল এ কাস্ট আগে।
ভিনস

উত্তর:


38

geometryডাব্লুজিএস 1984 ভৌগলিক ডেটা (এসআরআইডি 4326) ব্যবহার করে কলামগুলির সাথে বড় টেবিলগুলির সাথে ভাল জিওডেটিক কোয়েরি পারফরম্যান্স পাওয়ার দুটি কী রয়েছে :

  1. ব্যবহার ST_DWithinফাংশনটি যা কোনও উপলভ্য স্থানিক সূচক ব্যবহার করে অনুসন্ধান করে এবং কার্টেসিয়ান দূরত্ব সহ ভৌগলিক বৈশিষ্ট্যগুলি সন্ধান করবে
  2. ভূগোলের কাস্টে একটি অতিরিক্ত সূচক তৈরি করুন, তাই ST_DWithinএটি ব্যবহার করতে পারেন

আসুন আসুন দেখুন আসল বিশ্বে কী ঘটে। প্রথমে আমাদের দশ মিলিয়ন এলোমেলো পয়েন্টের একটি সারণী তৈরি এবং তৈরি করা দরকার:

DROP TABLE IF EXISTS example1
;

CREATE TABLE example1 (
    idcol   serial      NOT NULL,
    geomcol geometry        NULL,
    CONSTRAINT  example1_pk PRIMARY KEY (idcol),
    CONSTRAINT  enforce_srid CHECK (st_srid(geomcol) = 4326)
)
with (
    OIDS=FALSE
);

INSERT INTO example1(geomcol)
SELECT  ST_SetSRID(
            ST_MakePoint(
            (random()*360.0) - 180.0,
            (acos(1.0 - 2.0 * random()) * 2.0 - pi()) * 90.0 / pi()),
            4326) as geomcol
FROM  generate_series(1, 1000000) vtab;

CREATE INDEX example1_spx ON example1 USING GIST (geomcol);
-- (took about 22 sec)

যদি আমরা ST_Distance কোয়েরি কার্যকর করি, আমরা আপনার প্রত্যাশিত পূর্ণ টেবিল স্ক্যানটি পেয়েছি:

EXPLAIN ANALYZE VERBOSE
SELECT  count(*)
FROM    example1
WHERE   ST_Distance(geomcol::geography,ST_SetSRID(ST_MakePoint(6.9333,46.8167),4326)::geography) < 30 * 1609.34
;

Aggregate  (cost=274167.33..274167.34 rows=1 width=0) (actual time=4940.531..4940.532 rows=1 loops=1)
  Output: count(*)
  ->  Seq Scan on bob.example1  (cost=0.00..273334.00 rows=333333 width=0) (actual time=592.766..4940.509 rows=11 loops=1)
        Output: idcol, geomcol
        Filter: (_st_distance((example1.geomcol)::geography, '0101000020E61000005D6DC5FEB2BB1B40545227A089684740'::geography, 0::double precision, true) < 48280.2::double precision)
        Rows Removed by Filter: 999989
Planning time: 2.137 ms
Execution time: 4940.568 ms

এখন, আমরা যদি ব্যবহার ST_DWithinকরি তবে আমরা এখনও একটি পূর্ণ টেবিল স্ক্যান পাই (তত দ্রুত হলেও):

EXPLAIN ANALYZE VERBOSE
SELECT  count(*)
FROM    example1
WHERE   ST_DWithin(geomcol::geography,ST_SetSRID(ST_MakePoint(6.9333,46.8167),4326)::geography,30 * 1609.34)
;

Aggregate  (cost=405867.33..405867.34 rows=1 width=0) (actual time=908.716..908.716 rows=1 loops=1)
  Output: count(*)
  ->  Seq Scan on bob.example1  (cost=0.00..405834.00 rows=13333 width=0) (actual time=38.449..908.700 rows=7 loops=1)
        Output: idcol, geomcol
        Filter: (((example1.geomcol)::geography && '0101000020E61000005D6DC5FEB2BB1B40545227A089684740'::geography) AND ('0101000020E61000005D6DC5FEB2BB1B40545227A089684740'::geography && _st_expand((example1.geomcol)::geography, 48280.2::double precision) (...)
        Rows Removed by Filter: 999993
Planning time: 2.017 ms
Execution time: 908.763 ms

এবং এটিই শেষ টুকরো - প্রচ্ছদ সূচক তৈরি করা (কাস্ট ভূগোল):

CREATE INDEX example1_gpx ON example1 USING GIST (geography(geomcol));
-- (Takes an extra 13 sec)

EXPLAIN ANALYZE VERBOSE
SELECT  count(*)
FROM    example1
WHERE   ST_DWithin(geomcol::geography,ST_SetSRID(ST_MakePoint(6.9333,46.8167),4326)::geography,30 * 1609.34)
;

Aggregate  (cost=96538.95..96538.96 rows=1 width=0) (actual time=0.775..0.775 rows=1 loops=1)
  Output: count(*)
  ->  Bitmap Heap Scan on bob.example1  (cost=8671.62..96505.62 rows=13333 width=0) (actual time=0.586..0.769 rows=19 loops=1)
        Output: idcol, geomcol
        Recheck Cond: ((example1.geomcol)::geography && '0101000020E61000005D6DC5FEB2BB1B40545227A089684740'::geography)
        Filter: (('0101000020E61000005D6DC5FEB2BB1B40545227A089684740'::geography && _st_expand((example1.geomcol)::geography, 48280.2::double precision)) AND _st_dwithin((example1.geomcol)::geography, '0101000020E61000005D6DC5FEB2BB1B40545227A089684740':: (...)
        Rows Removed by Filter: 14
        Heap Blocks: exact=33
        ->  Bitmap Index Scan on example1_gpx  (cost=0.00..8668.29 rows=200000 width=0) (actual time=0.384..0.384 rows=33 loops=1)
              Index Cond: ((example1.geomcol)::geography && '0101000020E61000005D6DC5FEB2BB1B40545227A089684740'::geography)
Planning time: 2.572 ms
Execution time: 0.820 ms

অবশেষে, অপ্টিমাইজারটি স্থানিক সূচকটি ব্যবহার করছে, এবং এটি দেখায়, তবে বন্ধুদের মধ্যে তিনটি ক্রমের পরিমাণ কী?

কিছু সতর্কতা:

  • আমি একটি ডাটাবেস নার্ড, তাই আমার বাড়ির পিসি ডাটাবেস ডিফল্ট টেবিল স্পেসের জন্য 16 গিগাবাইট র‌্যাম, ছয় 3.3 গিগাহার্টজ কোর এবং একটি 256 জিবি এসএসডি পেয়েছে; আপনার মাইলেজ পরিবর্তিত হতে পারে

  • ক্যাশে "গরম" পৃষ্ঠাগুলি সম্পর্কে শ্রদ্ধার সাথে খেলার ক্ষেত্রটি সমতল করতে আমি প্রতিটি ক্যোয়ারির আগে সৃষ্টি এসকিউএল পুনরায় চালিত করেছি, তবে এটি কিছুটা ভিন্ন ফলাফল আনতে পারে কারণ একই র্যান্ডম বীজ বিভিন্ন রানের জন্য ব্যবহার করা হয়নি

এবং একটি নোট:

  • আমি সমান-অঞ্চল বিতরণের জন্য আর্ক-কোসাইন ব্যবহার করতে মূল {-90, + 90} অক্ষাংশের পরিসীমাটি চিহ্নিত করেছি (খুঁটির দিকে কম পক্ষপাতিত্বশীল)

1
স্ট্যাকেক্সচেঞ্জ সম্প্রদায়ের কাছে আমি পেয়েছি এটি সেরা উত্তরগুলির মধ্যে একটি। আমি এখনও এটি চেষ্টা করি নি তবে আপনি সম্পূর্ণরূপে বুঝতে পারার জন্য একটি সম্পূর্ণ উদাহরণ সরবরাহ করেছিলেন। আপনাকে অনেক ধন্যবাদ @ ভিনস।
andrerpena

1
জিওমকোলকে ভূগোল হিসাবে সংরক্ষণ না করার কোনও কারণ আছে কি? ST_Distance এবং ST_D উভয়ই ভৌগলিক আশা করে expect এবং যদি আমরা এটি করে থাকি তবে আমাদের ভৌগলিকের জন্য অতিরিক্ত সূচক ingালাই জ্যামিতির প্রয়োজন হবে না।
অ্যান্ডের্পেনা

এটি একটি পৃথক প্রশ্ন এবং যদি জিজ্ঞাসা করা হয় তবে এটি মতামত ভিত্তিক হিসাবে বন্ধ থাকবে।
ভিনস

1
এই ফলাফলটি গুগলে এসেছিল এবং আপনার উত্তরটির জন্য @ ভিনসকে ধন্যবাদ জানাই। একটি জিওগ্রাফিকে জোর করে জিন পয়েন্টটি দেওয়ার ছোট্ট পার্থক্যটি আমার জিজ্ঞাসার সময়টি ৪৩ সেকেন্ড থেকে গড়ে 10 মিনিট সেকেন্ডে নিয়েছে ..
রাগান্বিত 84

দুর্দান্ত পোস্ট, তবে আমি মনে করি `(acos (1.0 - 2 * এলোমেলো ()) * 180.0) / পাই ()) not সঠিক নয়। পরিসীমা -90 থেকে 90
hxd1011
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.