মাইএসকিউএল টেবিলটিতে একটি সারি বিদ্যমান কিনা তা পরীক্ষা করার সর্বোত্তম উপায়


337

আমি কোনও টেবিলে একটি সারি বিদ্যমান কিনা তা জানার চেষ্টা করছি। মাইএসকিউএল ব্যবহার করে, এই জাতীয় কোনও কোয়েরি করা কি ভাল:

SELECT COUNT(*) AS total FROM table1 WHERE ...

এবং মোটটি শূন্য নয় কিনা তা পরীক্ষা করে দেখুন বা এর মতো কোনও কোয়েরি করা ভাল:

SELECT * FROM table1 WHERE ... LIMIT 1

এবং কোন সারি ফিরে এসেছে কিনা তা পরীক্ষা করে দেখুন?

উভয় প্রশ্নের মধ্যে, WHERE ধারাটি একটি সূচক ব্যবহার করে।

উত্তর:


470

আপনি চেষ্টা করতে পারেন EXISTS:

SELECT EXISTS(SELECT * FROM table1 WHERE ...)

এবং ডকুমেন্টেশন অনুযায়ী , আপনি SELECTকিছু করতে পারেন ।

Ditionতিহ্যগতভাবে, একটি বিদ্যমান উপস্থিতি নির্বাচন করুন * দিয়ে শুরু হয়, তবে এটি নির্বাচন 5 বা নির্বাচন কলাম 1 বা কিছুতেই শুরু হতে পারে। মাইএসকিউএল যেমন সাবকোয়্যারিতে নির্বাচন তালিকা উপেক্ষা করে, তাই এটি কোনও পার্থক্য করে না।


30
সঙ্গে পরীক্ষা ...EXISTS( SELECT 1/0 FROM someothertable)। এসকিউএল সার্ভার এবং ওরাকল - এর জন্য *, 1 বা NUL ব্যবহার করা কোনও তাত্পর্যপূর্ণ হয় না কারণ WHERE মানদণ্ডের মিলের 1+ এর উপর ভিত্তি করে কেবলমাত্র বুলিয়ানের পরীক্ষা করে।
ওএমজি পনিজ

77
ছেলেরা, এই উত্তরের সাথে যুক্ত ডকুমেন্টেশনের ঠিক ঠিক আছে, ২ য় অনুচ্ছেদে বলা হয়েছে, "Traতিহ্যগতভাবে, একটি উপস্থিতি সাবকিউরিটি SELECT * দিয়ে শুরু হয়, তবে এটি সেলেক্ট 5 বা সেলেক্ট 1 বা অন্য কোনও কিছু দিয়ে শুরু হতে পারে My মাইএসকিউএল এ জাতীয় নির্বাচন তালিকা উপেক্ষা করে একটি subquery, সুতরাং এটি কোন পার্থক্য করে না। "
এমপেন

12
@ ক্রিসটমসপসন: বিবৃতি কার্যকর করা হলে কী হবে? মানে ফলাফলের সেটটিতে কী রয়েছে?
আশ্বিন

13
@ আশ্বিন, এতে 0 (অস্তিত্ব নেই) বা 1 (বিদ্যমান) আছে কিনা তা রয়েছে।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

10
আমি মনে করি যে আপনার ক্যোয়ারী অতিমাত্রায় প্রযোজ্য, আমি পরীক্ষা করেছি এবং এই ক্যোয়ারীটি SELECT 1 FROM table1 WHERE col = $var LIMIT 1আপনার প্রশ্নের চেয়ে আরও দ্রুত faster তাহলে আপনার ক্যোয়ারির সুবিধা কী?
শাফিজাদে

182

আমি সম্প্রতি এই বিষয়ে কিছু গবেষণা করেছি। ক্ষেত্রটি যদি কোনও পাঠ্য ক্ষেত্র, কোনও অনন্য ক্ষেত্র হয় তবে এটিকে বাস্তবায়নের উপায়টি আলাদা হতে হবে।

আমি একটি টেক্সট ক্ষেত্র দিয়ে কিছু পরীক্ষা করেছি। আমাদের কাছে 1 এম এন্ট্রি সহ একটি টেবিল রয়েছে তা বিবেচনা করে। 37 টি এন্ট্রি 'কিছু' সমান:

  • SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1সহ mysql_num_rows() : 0.039061069488525s। (অপেক্ষাকৃত দ্রুত)
  • SELECT count(*) as count FROM test WHERE text LIKE '%something% : 16.028197050095s।
  • SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%') : 0.87045907974243 এস।
  • SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1) : 0.044898986816406 এস।

তবে এখন, একটি বড় পিকে ক্ষেত্রের সাথে, কেবল একটি প্রবেশিকা '321321' এর সমান:

  • SELECT * FROM test2 WHERE id ='321321' LIMIT 1সাথে mysql_num_rows() : 0.0089840888977051 এস।
  • SELECT count(*) as count FROM test2 WHERE id ='321321' : 0.00033879280090332 এস।
  • SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321') : 0.00023889541625977 এস।
  • SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1): 0.00020313262939453 এস। (অপেক্ষাকৃত দ্রুত)

2
অতিরিক্ত উত্তরের জন্য ধন্যবাদ। কোনও পাঠ্য ক্ষেত্রটি বেশ সামঞ্জস্যপূর্ণ হওয়ার জন্য দুটি দ্রুততম বিকল্পের মধ্যে আপনি সময়ের মধ্যে পার্থক্যটি খুঁজে পেয়েছেন? পার্থক্যটি বড় বলে মনে হচ্ছে না এবং বেছে বেছে নির্বাচন করুন (নির্বাচন করুন 1 ... লিমিটেড 1) উভয় ক্ষেত্রেই বেশ ভাল বলে মনে হচ্ছে।
বার্নার্ড চেন

1
আপনি ঠিক বলেছেন, পাঠ্য ক্ষেত্রের সাথে সম্পর্কিত অন্যান্য ফলাফলের ক্ষেত্রে পার্থক্যটি এতটা গুরুত্বপূর্ণ নয়। তবুও, সম্ভবত ক্যোয়ারী আরও ভাল ব্যবহার করা হবেSELECT 1 FROM test WHERE texte LIKE '%something%' LIMIT 1
লরেন্ট ডাব্লু

আমি select 1 ... limit 1
মাইএসকিএল

4
@ লিটলনুবিতে পার্থক্য রয়েছে। নির্বাচন করুন ... সত্য এবং মিথ্যা মান দেয় (1 বা 0), যখন নির্বাচন 1 ... হয় 1 বা খালি দেয়। আপনার পরিস্থিতির উপর নির্ভর করে ভুয়া মান এবং খালি সেটের মধ্যে সূক্ষ্ম পার্থক্য রয়েছে।
কুইকপিক

@ লিটলনবি একটি দুর্দান্ত পয়েন্ট তৈরি করেছেন, এটি উপেক্ষা করা সহজ। সময়জ্ঞান হারিয়েছে উপরে পরীক্ষা হয় SELECT 1 FROM test WHERE ...ছাড়াই SELECT EXISTSএটি প্রায়। সম্ভবত একটি চুল দ্রুত সেভাবে হয়।
টুলমেকারস্টেভ

27

@ ক্রিসটম্পসনের উত্তরের একটি সংক্ষিপ্ত উদাহরণ

উদাহরণ:

mysql> SELECT * FROM table_1;
+----+--------+
| id | col1   |
+----+--------+
|  1 | foo    |
|  2 | bar    |
|  3 | foobar |
+----+--------+
3 rows in set (0.00 sec)

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1);
+--------------------------------------------+
| EXISTS(SELECT 1 FROM table_1 WHERE id = 1) |
+--------------------------------------------+
|                                          1 |
+--------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 9);
+--------------------------------------------+
| EXISTS(SELECT 1 FROM table_1 WHERE id = 9) |
+--------------------------------------------+
|                                          0 |
+--------------------------------------------+
1 row in set (0.00 sec)

একটি নাম ব্যবহার করে:

mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
+---------+
| mycheck |
+---------+
|       1 |
+---------+
1 row in set (0.00 sec)

18

আমার গবেষণায়, আমি ফলাফলটি নিম্নলিখিত গতিতে পেয়েছি তা খুঁজে পেতে পারি।

select * from table where condition=value
(1 total, Query took 0.0052 sec)

select exists(select * from table where condition=value)
(1 total, Query took 0.0008 sec)

select count(*) from table where condition=value limit 1) 
(1 total, Query took 0.0007 sec)

select exists(select * from table where condition=value limit 1)
(1 total, Query took 0.0006 sec) 

12

আমি মনে করি এটি উল্লেখ করা উপযুক্ত, যদিও মন্তব্যগুলিতে এটি স্পর্শ করা হয়েছিল যে এই পরিস্থিতিতে:

SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1

এর থেকে উচ্চতর:

SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1

এটি কারণ প্রথম ক্যোয়ারী সূচক দ্বারা সন্তুষ্ট হতে পারে, অন্যদিকে সারি সন্ধান করা প্রয়োজন (সম্ভবত সমস্ত টেবিলের কলামগুলি ব্যবহৃত সূচকে না থাকলে)।

LIMITধারাটি যুক্ত করা ইঞ্জিনটিকে কোনও সারি সন্ধান করার পরে থামতে দেয়।

প্রথম ক্যোয়ারীর সাথে তুলনীয় হওয়া উচিত:

SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)

যা ইঞ্জিনে একই সংকেত প্রেরণ করে (1 / * এখানে কোনও পার্থক্য নেই), তবে আমি ব্যবহার করার সময় অভ্যাসটিকে আরও শক্তিশালী করতে 1 লিখি EXISTS:

SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)

EXISTSকোনও সারি মেলে না এমন সময় আপনার যদি সুস্পষ্ট ফেরতের প্রয়োজন হয় তবে মোড়কটি যুক্ত করা অর্থপূর্ণ হতে পারে ।


4

আপনি ব্যবহার করতে না সুপারিশ Countকারণ গণনা সবসময় ডিবি ব্যবহারের জন্য অতিরিক্ত লোড তোলে SELECT 1এবং এটি ফেরৎ 1 যদি অধিকার আছে আপনার রেকর্ড অন্যথায় এটি নাল ফেরৎ এবং আপনি এটি সব ব্যবস্থা করতে সক্ষম।


2

একটি COUNT টি ক্যোয়ারী দ্রুততর, যদিও সম্ভবত এটি লক্ষণীয় নয়, তবে কাঙ্ক্ষিত ফলাফল পাওয়া পর্যন্ত উভয়ই যথেষ্ট।


4
এটি অবশ্য ডিবি নির্দিষ্ট। COUNT (*) পোস্টগ্র্রেএসকিউএল-তে ধীর বলে পরিচিত। পিকে কলামটি নির্বাচন করা ভাল হবে এবং এটি কোনও সারি দেয় কিনা তা দেখুন।
বালুস সি

3
COUNT (*) InnoDB এ ধীরে ধীরে
Will

2

অনেক সময় idসারিটির অটো ইনক্রিমেন্ট প্রাথমিক কী ( ) উপস্থিত থাকে এবং 0যদি তা না থাকে তবে তা পাওয়া খুব সহজ ।

এটি একটি একক ক্যোয়ারিতে এটি কীভাবে করা যায় তা এখানে:

SELECT IFNULL(`id`, COUNT(*)) FROM WHERE ...

শুধু IFNULL(id, 0)এখানে পরিবর্তে এখানে ব্যবহার করবেন না কেন COUNT(*)?
ইথান হোহেনসি


-1

আমি সাথে যেতে হবে COUNT(1)। এটির চেয়ে দ্রুততর COUNT(*)কারণ COUNT(*)পরীক্ষাগুলি দেখতে এই সারিটির কমপক্ষে একটি কলাম হয় কিনা! = নুল see আপনার এটির দরকার নেই, বিশেষত কারণ আপনার ইতিমধ্যে একটি শর্ত রয়েছে ( WHEREধারা)। COUNT(1)পরিবর্তে এর বৈধতা পরীক্ষা করে 1, যা সর্বদা বৈধ এবং পরীক্ষায় অনেক কম সময় নেয়।


8
-1 এটি ভুল। COUNT (*) কলামের মানগুলি দেখায় না - এটি কেবল সারিগুলির সংখ্যা গণনা করে। আমার উত্তরটি এখানে দেখুন: stackoverflow.com/questions/2876909/…
মার্ক বাইয়ার্স

6
COUNT টি () অনেক ধীর বিদ্যমান চেয়ে যেমন বিদ্যমান যখন এটি প্রথম একটি সারিতে খুঁজে বের করে আসতে পারে
উইল

-1

অথবা আপনি শর্তগুলিতে কাঁচা বর্গক্ষেত্র অংশ sertোকাতে পারেন তাই আমার 'শর্তাবলী' => অ্যারে রয়েছে ('সদস্য.ইড ইন না (সদস্যতার হিসাবে সদস্যপদ.ইম্বে_আইডি সদস্যতার মাধ্যমে নির্বাচন করুন'))


-2

COUNT(*) মাইএসকিউএলে অপ্টিমাইজ করা হয়েছে, সুতরাং পূর্ববর্তী ক্যোয়ারীটি সাধারণত বলার দ্রুত হবে বলে মনে হয়।


2
আপনি কি পুরো টেবিলের জন্য গণনাটি বাছাই করার জন্য মাইআইএসএএম যে অপটিমাইজেশনটির কথা উল্লেখ করছেন? আমি মনে করি না যে এখানে কোনও শর্ত থাকলে এটি সাহায্য করে helped
বার্নার্ড চেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.