PDA

View Full Version : سوال: نمایش 25 سطر از جدول در جدولهایی که حداقل 150 سطر دارن



i-php-i
سه شنبه 27 اردیبهشت 1390, 01:30 صبح
من یه سایت دارم که توش قابیلت ارسال مقالات وجود داره. از اونجایی که حدود 150 مقاله توش گذاشتم، موقع بازیابی باید تعداد مشخصی از این مقالات رو نمایش بدم. من 25 مقاله رو نمایش می دم.

برای اینکار اول یه کوری می فرستم تا تعداد کل مقالات به دست بیاد و بعد یه سری محاسبات ریاضی انجام می دم و بعد یه کوئری دیگه می فرستم و 25 مقاله رو بازیابی می کنم و نمایش می دم. در کوئری های بعدی 25 مقاله بعدی رو نمایش می دم.

لطفا بگید که این روش استاندارد هست یا اینکه باید از روش دیگه ای استفاده کنم؟

MMSHFE
سه شنبه 27 اردیبهشت 1390, 07:49 صبح
دوست گرامي، نميشه با ORDER BY عمل مرتب سازي رو برحسب فيلدي كه ميخواين انجام بدين و بعد با LIMIT ركوردهايي كه ميخواين رو بازيابي كنيد؟ براي مثال، دستور زير رو درنظر بگيرين:


SELECT * FROM `table_name` ORDER BY `field_name` LIMIT $start, $count

اين دستور، ابتدا اطلاعات جدول table_name رو برحسب field_name مرتب ميكنه و بعد، با شروع از ركورد شماره start$، به اندازه count$ ركورد جدا ميكنه و برميگردونه. اينطوري خيلي سريعتر به جواب ميرسين. ضمناً بعد از field_name ميتونيد از DESC براي مرتب سازي نزولي استفاده كنيد.
موفق باشيد.

AMIBCT
سه شنبه 27 اردیبهشت 1390, 08:37 صبح
اين تعداد نوشته نيازي به بهينه‌سازي بيشتري نداره

ولي براي بهينه‌سازي كارهايي كه مي‌شه انجام داد عبارتند از
كش كردن صفحات - يعني كل متن صفحه‌ي ايجاد شده با php رو يه جايي ذخيره كنيد و دفعات بعدي صفحه رو به صورت ايستا نمايش بديد - بايد دقت كنيد كه چه زماني لازمه تا كش بازسازي بشه
نگهداري تعداد مقالات در يه محل ديگه و كاهش مراجعه به پايگاه با كاهش دفعات شمارش مقالات
نگهداري شناسه‌ي آخرين رديف نمايش داده شده به جاي ترتيب نمايش اون . اين كار به سه دليل انجام مي‌شه( اول اينكه دستور Limit دستوري غيراستاندارد هست و فشار زيادي به پايگاه وارد مي‌كنه و دوم اينكه تضميني وجود نداره كه ترتيب نمايش داده‌ها هميشه ثابت باشه و سوم اينكه اگه نوشته‌اي وسط نوشته‌هاي قبلي اضافه يا كم بشه، كاربر مطابق انتظارش نتيجه‌ي دلخواه رو دريافت نمي‌كنه )

i-php-i
سه شنبه 27 اردیبهشت 1390, 09:58 صبح
دوست گرامي، نميشه با ORDER BY عمل مرتب سازي رو برحسب فيلدي كه ميخواين انجام بدين و بعد با LIMIT ركوردهايي كه ميخواين رو بازيابي كنيد؟ براي مثال، دستور زير رو درنظر بگيرين:


SELECT * FROM `table_name` ORDER BY `field_name` LIMIT $start, $count

اين دستور، ابتدا اطلاعات جدول table_name رو برحسب field_name مرتب ميكنه و بعد، با شروع از ركورد شماره start$، به اندازه count$ ركورد جدا ميكنه و برميگردونه. اينطوري خيلي سريعتر به جواب ميرسين. ضمناً بعد از field_name ميتونيد از DESC براي مرتب سازي نزولي استفاده كنيد.
موفق باشيد.

تعداد کل مقالات رو باید بدست بیاریم تا متوجه بشیم که مقالات رو باید در چند دسته 25 تایی تقسیم کنیم. شما این کار رو ضروری نمی دونید؟

i-php-i
سه شنبه 27 اردیبهشت 1390, 10:04 صبح
اين تعداد نوشته نيازي به بهينه‌سازي بيشتري نداره

ولي براي بهينه‌سازي كارهايي كه مي‌شه انجام داد عبارتند از
كش كردن صفحات - يعني كل متن صفحه‌ي ايجاد شده با php رو يه جايي ذخيره كنيد و دفعات بعدي صفحه رو به صورت ايستا نمايش بديد - بايد دقت كنيد كه چه زماني لازمه تا كش بازسازي بشه
نگهداري تعداد مقالات در يه محل ديگه و كاهش مراجعه به پايگاه با كاهش دفعات شمارش مقالات
نگهداري شناسه‌ي آخرين رديف نمايش داده شده به جاي ترتيب نمايش اون . اين كار به سه دليل انجام مي‌شه( اول اينكه دستور Limit دستوري غيراستاندارد هست و فشار زيادي به پايگاه وارد مي‌كنه و دوم اينكه تضميني وجود نداره كه ترتيب نمايش داده‌ها هميشه ثابت باشه و سوم اينكه اگه نوشته‌اي وسط نوشته‌هاي قبلي اضافه يا كم بشه، كاربر مطابق انتظارش نتيجه‌ي دلخواه رو دريافت نمي‌كنه )

بنظرم در هر صورت باید تعداد مقالات رو بدست آورد.

منظورتون از نگه داری تعداد مقالات در یه محل دیگه چیه؟ اگه منظورتون نگه داری تعداد مقالات توی فایله، فکر نکنم این کار روش درستی باشه چون اگه دو درخواست همزمان به فایل ارسال بشه، درخواستها به درستی اجرا نمی شن.

راه بهتر که بنظرم می رسه اینه که توی هر درخواست کاربر، تعداد مقالات رو توی سسشن ها نگه داری کنیم تا در درخواستهای بعدی دیگه احتیاجی به شمردن تعداد مقالات نباشه.

نظر شما چیه؟

MMSHFE
سه شنبه 27 اردیبهشت 1390, 10:14 صبح
با سلام، دوست گرامي AMIBCT (http://barnamenevis.org/member.php?73933-AMIBCT)، ميشه بفرماييد طبق چه مستنداتي ميگين LIMIT استاندارد نيست؟ و باز هم طبق كدوم مستندات ميفرماييد LIMIT به بانك اطلاعاتي فشار مياره؟ استفاده از فايلها رو به هيچ عنوان توصيه نميكنم چون در نهايت، سرعت كار با فايلها كمتر از DB هست و ضمناً LIMIT ساختار استاندارد MySQL هست كه معادل و بهتر بگم تكامل يافته TOP در T-SQL محسوب ميشه. براي به دست آوردن تعداد كل ركوردها هم راهي كه دوستمون (http://barnamenevis.org/member.php?191393-i-php-i) گفتن (ذخيره تعداد ركوردها در Session) راه مناسبي به نظر ميرسه. البته اگه از Cache به درستي استفاده بشه، گزينه مناسبي هست ولي بايد همونطور كه خودتون گفتين، بايد به بازه زماني تغيير اطلاعات هم توجه داشته باشيم كه خودش يك مشكل جدي محسوب ميشه.
موفق باشيد.

AMIBCT
سه شنبه 27 اردیبهشت 1390, 14:17 عصر
همين كه خودتون فرموديد در T-SQL وجود نداره سند اينكه اين دستور استاندارد نيست

علت استاندارد نبودنش هم اينه كه هيچ راهي براي پيدا كردن ركورد مثلا ۱۰۰ تا ۱۲۵ وجود نداره جز اينكه ۹۹ ركورد اول محاسبه و شمارش بشن و از ركورد ۱۰۰ به بعد نمايش داده بشه

روي ۱۰۰ تا ركورد شايد به چشم نياد
ولي وقتي تعداد ركوردها زياد شد و سرور لازم بود در هر ثانيه به چندين كاربر پاسخ بده. اونوقت براي هر پرس‌وجو چندين ثانيه زمان نياز خواهد بود و عملا سرور قفل خواهد شد

يه مطلب ديگه هم در پست قبلي نوشتم و اون اين بود كه هيچ تضميني براي ترتيب واكشي رديف‌ها وجود نداره
يعني ممكنه يه بار اول رديف x و بعد y واكشي بشه
و دفعه‌ي بعدي اول y و بعد x
يعني عملا دستور limit عملكردي نامشخص داره

i-php-i
سه شنبه 27 اردیبهشت 1390, 16:30 عصر
همين كه خودتون فرموديد در T-SQL وجود نداره سند اينكه اين دستور استاندارد نيست

علت استاندارد نبودنش هم اينه كه هيچ راهي براي پيدا كردن ركورد مثلا ۱۰۰ تا ۱۲۵ وجود نداره جز اينكه ۹۹ ركورد اول محاسبه و شمارش بشن و از ركورد ۱۰۰ به بعد نمايش داده بشه

روي ۱۰۰ تا ركورد شايد به چشم نياد
ولي وقتي تعداد ركوردها زياد شد و سرور لازم بود در هر ثانيه به چندين كاربر پاسخ بده. اونوقت براي هر پرس‌وجو چندين ثانيه زمان نياز خواهد بود و عملا سرور قفل خواهد شد

يه مطلب ديگه هم در پست قبلي نوشتم و اون اين بود كه هيچ تضميني براي ترتيب واكشي رديف‌ها وجود نداره
يعني ممكنه يه بار اول رديف x و بعد y واكشي بشه
و دفعه‌ي بعدي اول y و بعد x
يعني عملا دستور limit عملكردي نامشخص داره

فکر نکنم که دستور لیمیت انقدر بد کار کنه. امکانش هست یه سند معرفی کنید؟

MMSHFE
چهارشنبه 28 اردیبهشت 1390, 07:39 صبح
همين كه خودتون فرموديد در T-SQL وجود نداره سند اينكه اين دستور استاندارد نيست

علت استاندارد نبودنش هم اينه كه هيچ راهي براي پيدا كردن ركورد مثلا ۱۰۰ تا ۱۲۵ وجود نداره جز اينكه ۹۹ ركورد اول محاسبه و شمارش بشن و از ركورد ۱۰۰ به بعد نمايش داده بشه

روي ۱۰۰ تا ركورد شايد به چشم نياد
ولي وقتي تعداد ركوردها زياد شد و سرور لازم بود در هر ثانيه به چندين كاربر پاسخ بده. اونوقت براي هر پرس‌وجو چندين ثانيه زمان نياز خواهد بود و عملا سرور قفل خواهد شد

يه مطلب ديگه هم در پست قبلي نوشتم و اون اين بود كه هيچ تضميني براي ترتيب واكشي رديف‌ها وجود نداره
يعني ممكنه يه بار اول رديف x و بعد y واكشي بشه
و دفعه‌ي بعدي اول y و بعد x
يعني عملا دستور limit عملكردي نامشخص داره
با سلام، معذرت ميخوام ولي از كي تا حالا T-SQL شده SQL استاندارد؟ اگه اينطوري حساب كنيد، TOP هم توي SQL Server جزو استانداردها نيست! LIMIT هم معادل همون دستور با كمي امكانات بيشتر توي MySQL هست. بعلاوه LIMIT عملكردش كاملاً مشخصه و اينطور نيست كه هيچ تضميني براي واكشي رديفها وجود نداشته باشه. پس ORDER BY رو براي تفريح گذاشتن؟ بعلاوه وقتي جدول كليد اصلي داشته باشه، اصلاً لازم نيست 99 ركورد اول شمارش بشن و بعد از ركورد 100 بياد نمايش بده. معذرت ميخوام اينطوري صحبت ميكنم، قصد توهين ندارم ولي انگار درس ساختمان داده ها رو نگذروندين! توي بحث Indexing يه موضوعي هست تحت عنوان دسترسي مستقيم كه با كمك طول ركوردها و ضرب اون در تعداد و جمع عدد حاصل با آدرس شروع ركوردها، مستقيماً به ركوردي كه ميخوايم ميرسيم. اگه اينطوري نباشه كه ديگه Indexing به هيچ دردي نميخوره.
لطفاً با دليل و مدرك صحبت كنيد تا افرادي كه اطلاعات اندكي دارند، به اشتباه نيفتند.
موفق باشيد.

AMIBCT
چهارشنبه 28 اردیبهشت 1390, 08:51 صبح
من با دليل صحبت كردم ولي ظاهرا شما علاقه‌اي به استدلال نداريد
بهتره به جاي پافشاري كمي به مطلبي كه نوشتم فكر كنيد

اون فرمولي هم كه شما زحمت كشيديد نوشتيد مربوط به DBMS نيست ( اگه اين طوري بود هر كسي براي خودش يه DBMS مي‌نوشت )

اينم نقل قول از راهنماي MySQL
If you are selecting only a few rows with LIMIT, MySQL uses indexes in some cases when normally it would prefer to do a full table scan.

اين تازه در مورد يه جدول هست اگه خروجي تركيبي از چند جدول باشه كه ديگه اوضاع وحشتناك مي‌شه

اين صفحه رو هم با هيتلر شكن ملاحظه بفرماييد

http://www.facebook.com/note.php?note_id=206034210932&_fb_noscript=1

i-php-i
چهارشنبه 28 اردیبهشت 1390, 14:11 عصر
دوستان بحث داره منحرف می شه.

برای جلوگیری از این کار، لطفا کدهایی که استفاده می کنید رو اینجا قرار بدید.

Mahdi.Spirit
چهارشنبه 28 اردیبهشت 1390, 15:50 عصر
دوستان بحث داره منحرف می شه.

...
اتفاقا بحث خوبي شد ،‌ كجاش منحرف شده ؟:لبخندساده:
من الان كه با دستور limit تست كردم وقتي تعداد ركوردها بيشتر از 50 هزار شد،‌ (براي محدوده "50000 تا 50010" ركورد) زمان جواب گرفتن 40 برابر بيشتر از محدوده "0 تا 10" شد! (يعني به دهم ثانيه رسيد ) درصورتي كه با شرط (where) تغيير خاصي نكرد (همون هزارم ثانيه باقي موند)!:متفکر:

i-php-i
چهارشنبه 28 اردیبهشت 1390, 17:58 عصر
اتفاقا بحث خوبي شد ،‌ كجاش منحرف شده ؟:لبخندساده:
من الان كه با دستور limit تست كردم وقتي تعداد ركوردها بيشتر از 50 هزار شد،‌ (براي محدوده "50000 تا 50010" ركورد) زمان جواب گرفتن 40 برابر بيشتر از محدوده "0 تا 10" شد! (يعني به دهم ثانيه رسيد ) درصورتي كه با شرط (where) تغيير خاصي نكرد (همون هزارم ثانيه باقي موند)!:متفکر:
وقتی از لیمیت استفاده می کنیم نیازی نیست که ردیفهای جدول ها به ترتیب باشن و اگر چند ردیف از جدول رو حذف کنیم دستور لیمیت مشکلی نداره، اما اگر چند ردیف از جدول حذف بشه چطور باید از where استفاده می کنیم؟

چون شرط where باید یه یه مبنای محاسباتی داشته باشه و اگه ترتیب سطرهای جدول به هم بخوره این شرط به خوبی اجرا نمی شه.

لطفا توضیح بدید.

اون کد که برای تست کردن 50000 ردیف رو بکار بردید رو لطفا اینجا قرار بدید.

Mahdi.Spirit
چهارشنبه 28 اردیبهشت 1390, 23:00 عصر
وقتی از لیمیت استفاده می کنیم نیازی نیست که ردیفهای جدول ها به ترتیب باشن و اگر چند ردیف از جدول رو حذف کنیم دستور لیمیت مشکلی نداره، اما اگر چند ردیف از جدول حذف بشه چطور باید از where استفاده می کنیم؟
چون شرط where باید یه یه مبنای محاسباتی داشته باشه و اگه ترتیب سطرهای جدول به هم بخوره این شرط به خوبی اجرا نمی شه.
لطفا توضیح بدید.
اون کد که برای تست کردن 50000 ردیف رو بکار بردید رو لطفا اینجا قرار بدید.

من نخواستم بگم از where‌ استفاده كنيد يا نكنيد ،‌ ميخواستم نشون بدم كه براي ركوردهاي بالا دستور Limit ‌ همه رو از اول تا اونجايي كه ابتداي limit مشخص كرديم ميخونه !

كد خاصي استفاده نكردم ،‌همين كوئريه :

SELECT * FROM table LIMIT 50000,10

فقط مستقيم توي phpmyadmin اجرا كردم زمانش رو همونجا ديدم!
فقط نكته كه هست اينه كه اين زمان به تعداد فيلدها هم بستگي داره هر چه كمتر سريعتر

براي راه حلش يكي اينه كه اگه يك صفحه يك صفحه اطلاعات رو مياريد ميتونيد از where‌ استفاده كنيد و آخرش يه limit بزاريد مثلا اينطوري :

SELECT *
FROM table
WHERE id > 50000
ORDER BY id
LIMIT 10

بعدش id آخرين ركورد بدست اومده رو توي شرط بعدي بزارين و...

ولي اگه ميخواين كاربر مستقيم به يه صفحه خاص بره فكر كنم بايد از همون limit استفاده كنيد !

i-php-i
پنج شنبه 29 اردیبهشت 1390, 00:28 صبح
من نخواستم بگم از where‌ استفاده كنيد يا نكنيد ،‌ ميخواستم نشون بدم كه براي ركوردهاي بالا دستور Limit ‌ همه رو از اول تا اونجايي كه ابتداي limit مشخص كرديم ميخونه !

كد خاصي استفاده نكردم ،‌همين كوئريه :

SELECT * FROM table LIMIT 50000,10

فقط مستقيم توي phpmyadmin اجرا كردم زمانش رو همونجا ديدم!
فقط نكته كه هست اينه كه اين زمان به تعداد فيلدها هم بستگي داره هر چه كمتر سريعتر

براي راه حلش يكي اينه كه اگه يك صفحه يك صفحه اطلاعات رو مياريد ميتونيد از where‌ استفاده كنيد و آخرش يه limit بزاريد مثلا اينطوري :

SELECT *
FROM table
WHERE id > 50000
ORDER BY id
LIMIT 10

بعدش id آخرين ركورد بدست اومده رو توي شرط بعدي بزارين و...

ولي اگه ميخواين كاربر مستقيم به يه صفحه خاص بره فكر كنم بايد از همون limit استفاده كنيد !

من همیشه از where استفاده می کنم. فکر کردم که منظورتون اینه که بجای لیمیت از where استفاده کنیم..