ডাবল জিজ্ঞাসা ছাড়াই মাইএসকিউএল পৃষ্ঠাগুলি?


115

আমি ভাবছিলাম যে কোনও মাইএসকিউএল কোয়েরি থেকে ফলাফলের সংখ্যা পাওয়ার কোনও উপায় ছিল এবং একই সময়ে ফলাফলগুলি সীমাবদ্ধ করে ফেলুন।

পৃষ্ঠাগুলিটি যেভাবে কাজ করে (যেমন আমি এটি বুঝতে পারি), প্রথমে আমি এর মতো কিছু করি

query = SELECT COUNT(*) FROM `table` WHERE `some_condition`

আমি নাম_আর (ক্যোয়ারী) পাওয়ার পরে আমার কাছে ফলাফলের সংখ্যা রয়েছে। তবে তারপরে আসলে আমার ফলাফলগুলি সীমাবদ্ধ করতে আমাকে দ্বিতীয় কোয়েরিটি করতে হবে যেমন:

query2 = SELECT COUNT(*) FROM `table` WHERE `some_condition` LIMIT 0, 10

আমার প্রশ্ন: উভয়ই কি দেওয়া হবে এমন মোট ফলাফলের পুনরুদ্ধার করার আছে এবং একক ক্যোয়ারিতে ফলাফলগুলি সীমাবদ্ধ করেছে? অথবা এটি করার আরও কোনও কার্যকর উপায়। ধন্যবাদ!


7
যদিও আপনার কাছে ক্যুয়ার 2
dlofrodloh

উত্তর:


66

না, এই যে পৃষ্ঠা প্রয়োগ করতে চান এমন কতগুলি অ্যাপ্লিকেশনকে তা করতে হবে। এটি নির্ভরযোগ্য এবং বুলেট-প্রুফ, যদিও এটি কোয়েরিটি দুবার করে। তবে আপনি কয়েক সেকেন্ডের জন্য গণনাটি ক্যাশে করতে পারেন এবং এটি অনেক সাহায্য করবে।

অন্য উপায়টি হল SQL_CALC_FOUND_ROWSক্লজটি ব্যবহার করা এবং তারপরে কল করা SELECT FOUND_ROWS()FOUND_ROWS()এরপরে আপনাকে কলটি স্থাপন করতে হবে তা বাদ দিয়েও এখানে একটি সমস্যা রয়েছে: মাইএসকিউএল-তে একটি বাগ রয়েছে যে এই টিকলগুলি ORDER BYপ্রশ্নগুলিকে প্রভাবিত করে যেগুলি দুটি প্রশ্নের তুচ্ছ পদ্ধতির চেয়ে বড় টেবিলগুলিতে আরও ধীর করে তোলে।


2
এটি কোনও রেস-কন্ডিশনের প্রমাণ নয়, যদি না আপনি কোনও লেনদেনের মধ্যে দুটি প্রশ্ন না করেন। যদিও এটি সাধারণত কোনও সমস্যা নয়।
নিকজাইক

"নির্ভরযোগ্য" দ্বারা আমি বুঝাচ্ছিলাম যে এসকিউএল নিজেই সর্বদা আপনার ফলাফলটি ফিরিয়ে আনবে এবং "বুলেট-প্রুফ" দ্বারা আমি বোঝাতে চাইছি যে এসকিউএল আপনি কী ব্যবহার করতে পারবেন তাতে কোনও মাইএসকিউএল বাগ নেই। আমি উল্লিখিত বাগ অনুসারে অর্ডার বাই এবং লিমিটেডের সাথে এসকিউএল_সিএলসি_ফাউND_ROWS ব্যবহারের বিপরীতে।
স্ট্যাটিকসান

5
জটিল ক্যোয়ারিতে, একই ক্যোয়ারিতে গণনা আনতে SQL_CALC_FOUND_ROWS ব্যবহার করা দুটি পৃথক ক্যোয়ারী করার চেয়ে প্রায় সর্বদা ধীর হবে। এটি কারণ এটির অর্থ হ'ল সীমা নির্বিশেষে সমস্ত সারি পুরোপুরি পুনরুদ্ধার করতে হবে, তবে কেবলমাত্র LIMIT দফাতে নির্দিষ্ট করাগুলিকেই ফিরিয়ে দেওয়া হবে। আমার প্রতিক্রিয়া দেখুন যা লিঙ্ক আছে।
থোমাসরুটটার

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

68

আমি প্রায় দুটি জিজ্ঞাসা করি না।

কেবলমাত্র প্রয়োজনের তুলনায় আরও একটি সারিটি ফিরিয়ে দিন, কেবলমাত্র পৃষ্ঠায় 10 টি প্রদর্শন করুন, এবং যদি আরও কিছু প্রদর্শিত হয়, তবে "নেক্সট" বোতামটি প্রদর্শন করুন।

SELECT x, y, z FROM `table` WHERE `some_condition` LIMIT 0, 11
// iterate through and display 10 rows.

// if there were 11 rows, display a "Next" button.

আপনার ক্যোয়ারীটি প্রথমে সবচেয়ে প্রাসঙ্গিক অর্ডারে ফিরে আসা উচিত। সম্ভাবনাগুলি হ'ল, বেশিরভাগ লোক 412 এর মধ্যে 236 পৃষ্ঠায় যাওয়ার বিষয়ে চিন্তা করে না।

আপনি যখন গুগল অনুসন্ধান করেন এবং আপনার ফলাফল প্রথম পৃষ্ঠায় না থাকে, আপনি সম্ভবত নয়টি নয়, দুটি পৃষ্ঠায় যেতে পারেন।


42
আসলে, যদি আমি গুগল ক্যোয়ারির প্রথম পৃষ্ঠায় এটি না পাই তবে সাধারণত আমি পৃষ্ঠা নয়টিতে চলে যাই।
ফিল

3
@ ফিলিল আমি আগে এটি শুনেছি তবে কেন এটি করছ?
TK123

5
একটু দেরি হলেও এখানে আমার যুক্তি। কিছু অনুসন্ধান অনুসন্ধান ইঞ্জিন অপ্টিমাইজড লিঙ্ক ফার্মগুলিতে প্রাধান্য পায়। সুতরাং প্রথম কয়েকটি পৃষ্ঠা হ'ল বিভিন্ন খামার এটি 1 নম্বর পজিশনের জন্য লড়াই করছে, দরকারী ফলাফল সম্ভবত এখনও কোয়েরির সাথে জড়িত রয়েছে, কেবল শীর্ষে নয়।
ফিল

4
COUNTএকটি সামগ্রিক ফাংশন। আপনি কীভাবে একটি ক্যোয়ারিতে গণনা এবং সমস্ত ফলাফলগুলি ফেরত পাবেন ? উপরের ক্যোয়ারীটি কেবল 1 সারি ফেরত দেবে, তাতে LIMITসেট করা যাই হোক না কেন । আপনি যদি যোগ করেন তবে GROUP BYএটি সমস্ত ফলাফল ফিরিয়ে দেবে তবে ফলাফলটি COUNTসঠিক হবে না
pixelfreak

2
এটি পারকোনার দ্বারা প্রস্তাবিত একটি পদ্ধতির মধ্যে রয়েছে: পারকোনা.
2008

26

ডাবল-জিজ্ঞাসা করা এড়ানোর জন্য আরেকটি পদ্ধতি হ'ল প্রথমে LIMIT টি ধারা ব্যবহার করে বর্তমান পৃষ্ঠার জন্য সমস্ত সারি আনা, তারপরে সর্বাধিক সংখ্যক সারি পুনরুদ্ধার করা হয় তবে কেবলমাত্র দ্বিতীয় COUNT (*) কোয়েরি করুন।

অনেক অ্যাপ্লিকেশনে, সর্বাধিক সম্ভাব্য ফলাফলটি হবে যে ফলাফলগুলি সমস্তই একটি পৃষ্ঠায় মাপসই হয় এবং পৃষ্ঠাগুলি সম্পাদন করা আদর্শের চেয়ে ব্যতিক্রম। এই ক্ষেত্রে, প্রথম ক্যোয়ারী সর্বাধিক সংখ্যক ফলাফল পুনরুদ্ধার করবে না।

উদাহরণস্বরূপ, স্ট্যাকওভারফ্লো প্রশ্নের উত্তর খুব কমই দ্বিতীয় পৃষ্ঠায় ছড়িয়ে পড়ে। একটি উত্তরের মন্তব্যগুলি খুব কমই 5 এর সীমা ছাড়িয়ে যায় বা এগুলি সমস্ত দেখানোর প্রয়োজন হয়।

সুতরাং এই অ্যাপ্লিকেশনগুলিতে আপনি প্রথমে কেবল একটি সীমাবদ্ধতার সাথে কেবল একটি ক্যোয়ারী করতে পারেন, এবং তারপরে যতক্ষণ না এই সীমাটি পৌঁছে যায়, আপনি ঠিক কীভাবে দ্বিতীয় সারির (*) কোয়েরি করার দরকার নেই সেখানে কতগুলি সারি রয়েছে তা জানেন know বেশিরভাগ পরিস্থিতিতে coverাকুন।


1
@ থোমাস্রুটটার আমার একই পদ্ধতি ছিল, তবে আজ এটির সাথে একটি ত্রুটি আবিষ্কার করে। ফলাফলের চূড়ান্ত পৃষ্ঠায় পৃষ্ঠাগুলি তথ্য থাকবে না। উদাহরণস্বরূপ, আসুন আমরা বলি যে প্রতিটি পৃষ্ঠার 25 টি ফলাফল হওয়া উচিত, শেষ পৃষ্ঠায় সম্ভবত এটির অনেকগুলিই থাকবে না, আসুন এটির 7 টি আছে বলে ধরা যাক ... এর অর্থ গণনা (*) কখনই চালানো হবে না, এবং তাই কোনও পৃষ্ঠাগুলি প্রদর্শিত হবে না ব্যবহারকারী।
ডেল্ল্যাসি

2
না - যদি আপনি 200 ফলাফলের কথা বলে থাকেন তবে আপনি পরবর্তী 25 টি জিজ্ঞাসা করেন এবং আপনি কেবল 7 টি ফিরে পেয়েছেন, এটি আপনাকে জানায় যে ফলাফলের মোট সংখ্যা 207 এবং সুতরাং আপনাকে COUNT (*) এর সাথে আর কোনও জিজ্ঞাসা করার দরকার নেই কারণ আপনি ইতিমধ্যে জানেন যে এটি কী বলছে। পৃষ্ঠাগুলি দেখানোর জন্য আপনার প্রয়োজনীয় সমস্ত তথ্য আছে। ব্যবহারকারী যদি পৃষ্ঠাটি না দেখায় আপনার যদি সমস্যা হয় তবে আপনার অন্য কোথাও একটি বাগ রয়েছে।
থোমাসরুটটার

15

একটি পরিস্থিতিতে না করানোর চেয়ে দুটি পৃথক ক্যোয়ারিতে এটি করা বেশিরভাগ পরিস্থিতিতে এটির চেয়ে দ্রুত এবং কম সংস্থান নিবিড়, যদিও এটিকে পাল্টা স্বজ্ঞাত মনে হয়।

আপনি যদি এসকিউএল_এএলসিএলসি_এফএউআউআরআরআউআরআউএস ব্যবহার করেন, তবে বড় টেবিলের জন্য এটি আপনার ক্যোয়ারিকে আরও ধীর করে তোলে, দুটি ক্যুরিয়ার কার্যকর করার চেয়েও ধীরে ধীরে ধীরে ধীরে ধীরে প্রথমটি একটি COUNT (*) এবং দ্বিতীয়টি একটি লিমিটেড সহ। এর কারণটি হ'ল এসকিউএল_সিএলসি_ফুআউআরআরআউব্লুএস এর ফলে আগের পরিবর্তে সারিগুলি আনার পরে লিমিটের ধারাটি প্রয়োগ করা হয় , সুতরাং এটি সীমা প্রয়োগের আগে সমস্ত সম্ভাব্য ফলাফলের জন্য পুরো সারিটি নিয়ে আসে। এটি কোনও সূচকের দ্বারা সন্তুষ্ট হতে পারে না কারণ এটি আসলে ডেটা নিয়ে আসে।

আপনি যদি দুটি ক্যোয়ারী পদ্ধতির কাছে যান, প্রথমটি কেবলমাত্র COUNT (*) এনেছে এবং প্রকৃত ডেটা সংগ্রহ করছে না, এটি আরও দ্রুত সন্তুষ্ট হতে পারে কারণ এটি সাধারণত সূচকগুলি ব্যবহার করতে পারে এবং এর জন্য প্রকৃত সারির ডেটা আনতে হবে না প্রতিটি সারি এটি তাকান। তারপরে, দ্বিতীয় ক্যোয়ারিতে কেবল প্রথম $ অফসেট + $ সীমা সারিগুলি দেখতে হবে এবং তারপরে ফিরে আসবে।

মাইএসকিউএল সম্পাদনা ব্লগের এই পোস্টটি আরও ব্যাখ্যা করে:

http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

পৃষ্ঠাগুলি অনুকূলকরণ সম্পর্কিত আরও তথ্যের জন্য, এই পোস্টটি এবং এই পোস্টটি দেখুন


2

আমার উত্তর দেরিতে হতে পারে তবে আপনি দ্বিতীয় সন্ধানটি (সীমা সহ) এড়িয়ে যেতে পারেন এবং কেবল আপনার পিছনের শেষ স্ক্রিপ্টের মাধ্যমে তথ্য ফিল্টার করতে পারেন। উদাহরণস্বরূপ পিএইচপি-তে আপনি এমন কিছু করতে পারেন:

if($queryResult > 0) {
   $counter = 0;
   foreach($queryResult AS $result) {
       if($counter >= $startAt AND $counter < $numOfRows) {
            //do what you want here
       }
   $counter++;
   }
}

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

বিষয়টিতে এখানে একটি ভাল পঠন রয়েছে: http://www.percona.com/ppc2009/PPC2009_mysql_pagination.pdf


লিংক এর মৃত, আমি এই সঠিক এগুলির মধ্যে একটি: percona.com/files/presentations/ppc2009/... । সম্পাদনা করবে না কারণ এটি নিশ্চিত কিনা not
হেক্টরগার 87

1
query = SELECT col, col2, (SELECT COUNT(*) FROM `table`) AS total FROM `table` WHERE `some_condition` LIMIT 0, 10

16
এই ক্যোয়ারী সারণীতে রেকর্ডের মোট সংখ্যাটি দেয়; শর্তের সাথে মেলে এমন রেকর্ডের সংখ্যা নয়।
লরেন্স বরসন্তী

1
পৃষ্ঠা রচনার জন্য রেকর্ডের মোট সংখ্যা হ'ল (@ লরেন্স)।
imme

ওহ, ভাল, কেবল whereঅভ্যন্তরীণ ক্যোয়ারিতে limit
ক্লজটি যুক্ত করুন

সাব-কোয়েরি গণনা (*) এর একই প্রয়োজন যেখানে ক্লজ অন্যথায় এটি ফলাফলের সঠিক সংখ্যাটি ফিরিয়ে আনবে না
AKrush95

1

2020 এ যে কোনও উত্তর খুঁজছেন তাদের জন্য। মাইএসকিউএল ডকুমেন্টেশন অনুসারে:

"এসকিউএল_এএলসিএলসি_উউউউআরআউআরআউআরআউআরআউএস কোয়েরি সংশোধনকারী এবং তার সাথে থাকা FOUND_ROWS () ফাংশনটি মাইএসকিউএল 8.0.17 হিসাবে অবহিত করা হয়েছে এবং ভবিষ্যতের মাইএসকিউএল সংস্করণে সরানো হবে a প্রতিস্থাপন হিসাবে, আপনার সীমাটি সীমাবদ্ধতার সাথে কার্যকর করার কথা বিবেচনা করুন, এবং তারপরে COUNT (*) এর সাথে একটি দ্বিতীয় কোয়েরি বিবেচনা করুন এবং অতিরিক্ত সারি রয়েছে কিনা তা নির্ধারণের জন্য লিমিট ছাড়াই ""

আমার ধারণা এটি স্থির করে les

https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_found-rows


0

আপনি সাব-কোয়েরিতে বেশিরভাগ ক্যোয়ারী পুনরায় ব্যবহার করতে পারেন এবং এটি একটি সনাক্তকারীতে সেট করতে পারেন। উদাহরণস্বরূপ একটি মুভি ক্যোয়ারী যা রানটাইম দ্বারা আদেশযুক্ত অক্ষরের মুভিগুলি সন্ধান করে তা আমার সাইটে এটির মতো দেখাবে।

SELECT Movie.*, (
    SELECT Count(1) FROM Movie
        INNER JOIN MovieGenre 
        ON MovieGenre.MovieId = Movie.Id AND MovieGenre.GenreId = 11
    WHERE Title LIKE '%s%'
) AS Count FROM Movie 
    INNER JOIN MovieGenre 
    ON MovieGenre.MovieId = Movie.Id AND MovieGenre.GenreId = 11
WHERE Title LIKE '%s%' LIMIT 8;

মনে রাখবেন যে আমি কোনও ডেটাবেস বিশেষজ্ঞ নই, এবং আশা করছি যে কেউ এটি আরও কিছুটা ভাল করতে সক্ষম হবেন। এটি সরাসরি এসকিউএল কমান্ড লাইন ইন্টারফেস থেকে এটি চলমান স্থির হিসাবে তারা উভয়ই আমার ল্যাপটপে ~ 0.02 সেকেন্ড নেয়।


-14
SELECT * 
FROM table 
WHERE some_condition 
ORDER BY RAND()
LIMIT 0, 10

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