পোস্টজিআইএস জ্যামিতি কলামে SELECT DISTINCT এর যথার্থতা কী?


19

আমি অবাক হয়েছি SELECT DISTINCTপোস্টজিআইএস জ্যামিতিতে অপারেটরের যথার্থতা কী । আমার সিস্টেমে, নিম্নলিখিত কোয়েরিটি আমাকে 5 এর একটি গণনা দেয়, যার অর্থ যে thatোকানো পয়েন্টগুলি 1e-5 এর চেয়ে কম আলাদা হয় এবং আমি নিশ্চিত নই যে এটি পোস্টজিআইএসের একটি বৈশিষ্ট্য, আমার ইনস্টলেশনটির একটি সমস্যা? বা একটি বাগ

কেউ কি জানেন যে এটি প্রত্যাশিত আচরণ?

CREATE TEMP TABLE test (geom geometry);
INSERT INTO test
    VALUES 
        (St_GeomFromText('POINT (0.1 0.1)')),
        (St_GeomFromText('POINT (0.001 0.001)')),
        (St_GeomFromText('POINT (0.0001 0.0001)')),
        (St_GeomFromText('POINT (0.00001 0.00001)')),
        (St_GeomFromText('POINT (0.000001 0.000001)')),
        (St_GeomFromText('POINT (0.0000001 0.0000001)')),
        (St_GeomFromText('POINT (0.00000001 0.00000001)')),
        (St_GeomFromText('POINT (0.000000001 0.000000001)'));

SELECT COUNT(*) FROM (SELECT DISTINCT geom FROM test) AS test;

 count 
-------
     5
(1 row)

আমি ব্যাবহার করছি:

$ psql --version
psql (PostgreSQL) 9.3.1

এবং

SELECT PostGIS_full_version();
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
POSTGIS="2.1.1 r12113" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.10.1, released 2013/08/26" LIBXML="2.7.3" LIBJSON="UNKNOWN" RASTER

OSX 10.9 এ

উত্তর:


18

আমি অবাক হয়েছি এটি বেশ মোটা, কিন্তু এটি আছে। এটি প্রতি ডিস্টিন্ট নয়, এটি '=' অপারেটর, যা জ্যামিতির জন্য 'সূচি কীগুলির সমতা' হিসাবে সংজ্ঞায়িত হয়েছে যার অর্থ কার্যত '32-বিট বাউন্ডিং বাক্সগুলির সমতা'।

সরাসরি '=' ব্যবহার করে আপনি একই প্রভাব দেখতে পাবেন,

select 'POINT (0.000000001 0.000000001)'::geometry = 'POINT (0.000000001 0.000001)'::geometry;

select 'POINT (0.000000001 0.000000001)'::geometry = 'POINT (0.000000001 0.00001)'::geometry;

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

এবং অবশ্যই এখন প্রচুর অ্যাপ্লিকেশন / ব্যবহারকারীগণ বিদ্যমান আচরণ যেমন অভ্যন্তরীণভাবে অভ্যন্তরীণ করেছে, সুতরাং "উন্নতি" এটি অনেক লোকের জন্য ডাউনগ্রেড হবে। পরিবর্তে ST_AsBinary (geom) এ আপনার সেট গণনা করে আপনি একটি "যথাযথ" স্বতন্ত্র করতে পারেন, যা বাইটিয়া আউটপুটগুলিতে সঠিক সমতা পরীক্ষা করবে।


এবং আমরা কী ধরে নিতে পারি ST_AsBinary (geom) তুলনামূলকভাবে খুব দ্রুত অপারেশন?
মার্টিন এফ

আপনার উত্তরের জন্য ধন্যবাদ, এটি আচরণটি ভালভাবে ব্যাখ্যা করে। আমি আসলে একটি জিওডজ্যাঙ্গো প্রকল্পে কাজ করছি, তাই আমি __equalsসেখানে ফিল্টারটি ব্যবহার করব যা আমার মনে হয় ST_Equals ফাংশনে অনুবাদ করে।
হলুদক্যাপ

1
হ্যাঁ ST_AsBinary দ্রুত। বাইটায় সমতা পরীক্ষাগুলি সম্ভবত মেমক্যাম্প জড়িত, যা খুব দ্রুত অপশন, তাই খুব ভয়াবহ হওয়া উচিত নয়।
পল রামসে

আপনি এখানে কী প্রস্তাব দিচ্ছেন, পলরামসে? SELECT DISTINCT ST_AsBinary(geom)? geomএটি ফলাফল হিসাবে একটি বাইনারি প্রতিনিধিত্ব দেয় । আপনি করতে পারতেন SELECT MAX(geom) FROM the_table GROUP BY ST_AsBinary(geom);(আমার মনে হয় এর মতো একটি সামগ্রিক ফাংশন MAX()প্রয়োজন SELECTকারণ ক্লজটি ফাংশন GROUP BYরিটার্নটি ব্যবহার করছে ST_AsBinary(), ক্ষেত্রটি নিজেই নয়)) এটি কি ভাল দেখাচ্ছে?
মার্টিন বারচ

7

প্রদত্ত পল রামসে এর চমৎকার ব্যাখ্যা কেন পরবর্তী প্রশ্ন হল কি এটা সম্পর্কে করা যাবে। SELECT DISTINCTজ্যামিতির ক্ষেত্রগুলিতে আপনি কীভাবে এবং এটি প্রত্যাশার মতো সম্পাদন করেছেন?

পলের উত্তরে, আমি ব্যবহারের প্রস্তাব দিয়েছিলাম SELECT MAX(geom) FROM the_table GROUP BY ST_AsBinary(geom);তবে MAX()ধীরে ধীরে, সম্ভবত টেবিল স্ক্যানের প্রয়োজন।

পরিবর্তে, আমি এটি দ্রুত হতে পেয়েছি:

SELECT DISTINCT ON (ST_AsBinary(geom)) geom FROM the_table;

4

পোস্টজিআইএস ২.৪-এর জন্য কেবলমাত্র একটি আপডেট ওপিতে SELECT DISTINCTপয়েন্ট ডেটার জন্য সঠিকভাবে কাজ করে:

CREATE TEMP TABLE test (geom geometry);
CREATE TABLE
user=> INSERT INTO test
user->     VALUES 
user->         (St_GeomFromText('POINT (0.1 0.1)')),
user->         (St_GeomFromText('POINT (0.001 0.001)')),
user->         (St_GeomFromText('POINT (0.0001 0.0001)')),
user->         (St_GeomFromText('POINT (0.00001 0.00001)')),
user->         (St_GeomFromText('POINT (0.000001 0.000001)')),
user->         (St_GeomFromText('POINT (0.0000001 0.0000001)')),
user->         (St_GeomFromText('POINT (0.00000001 0.00000001)')),
user->         (St_GeomFromText('POINT (0.000000001 0.000000001)'));
INSERT 0 8
user=> 
user=> SELECT COUNT(*) FROM (SELECT DISTINCT geom FROM test) AS test;
 count 
-------
     8
(1 row)

এবং

user=> select 'POINT (0.000000001 0.000000001)'::geometry = 'POINT (0.000000001 0.000001)'::geometry;
 ?column? 
----------
 f
(1 row)

user=> 
user=> select 'POINT (0.000000001 0.000000001)'::geometry = 'POINT (0.000000001 0.00001)'::geometry;
 ?column? 
----------
 f
(1 row)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.