• 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
از select count(*) استفاده کنید
#1
از یکی از اعضای همین انجمن (اسمشو نمیگم Big Grin) خونده بودم یه جایی که میگفت به جای
کد:
select count(*)
از مثلا
کد:
select count(id)
استفاده کنن

منم یه تست روی 7 میلیون رکورد گرفتم Big Grin
count(*) از همه بهتر بود
کد:
select count(id) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0.952 sec. */
select count(*) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0.749 sec. */
select count(title) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 14.477 sec. */
select count(slug) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 1.997 sec. */
select count(status) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 1.014 sec. */
select count(*) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0.109 sec. */
select count(id) from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0.109 sec. */
select count(*) _c from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0.749 sec. */
select count(id) _c from post;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0.827 sec. */

اینم یه تست دیگه روی 60 میلیون رکورد Cool
کد:
select count(*) _c from tag;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 21.716 sec. */
select count(post_id) _c from tag;
/* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 23.697 sec. */

پس از count(*) استفاده کنید Smile

اون بالاییه Mysql بود البته mariadb5.5 انجین innodb
دقیقا همون داده ها رو توی postgresql دارم (برای مقایسه سنگین میخواستم)

دیگه گفتم شمام ببنید همون کوئری ها رو توی postgresql9.3
7 میلیون رکورد
کد:
select count(id) from post;
/* 1 row (2.473 s)  */
select count(*) from post;
/* 1 row (0.554 s) */
select count(title) from post;
/* 1 row (7.254 s) */
select count(slug) from post;
/* 1 row (1.067 s) */
select count(status) from post;
/* 1 row (4.785 s) */
select count(*) from post;
/* 1 row (0.556 s)  */
select count(id) from post;
/* 1 row (0.582 s)  */
select count(*) _c from post;
/* 1 row (0.538 s)  */
select count(id) _c from post;
/* 1 row (0.586 s) */

و اینم نتیجه روی 60 میلیون رکورد
کد:
select count(*) _c from tag;
/* 1 row (5.895 s) */
select count(post_id) _c from tag;
/* 1 row (6.023 s) */
یه مقایسه هم توی کانال تلگرامی انجام دادم خواستید ببینید
telegram.me/zagroswebafzar
  پاسخ
تشکر شده توسط : ayoubsys
#2
آزمایشتو بذار در کوزه الکلشو بخور Big Grin

اون عضو اون مطلب رو 6 سال پیش با MySQL 5.0 و انجین MyISAM تست زده بود:
http://forum.iranphp.org/Thread-مقایسه-س...ed#pid9522
درصورتی که تو الان با MySQL 5.6 و انجین InnoDb زدی - اونم معلوم نیست چه نوعی از فیلد/مقدار

درضمن سرعت پردازش مقدار null با not null خیلی خیلی فرق میکنه
همچنین با where یا بدون where بودنش، مخصوصاً درمورد innodb که بدون where درمورد count(*) ترکونه


اینو الان کیلویی گرفتم نمیدونم اگه جاییش اشتباه کرده باشم:
MySQL 5.6.14 - MyISAM - 1394
10000 رکورد
count(*) - varchar_null
0.328 sec


10000 رکورد
count(FIELD) - varchar_null
0.015 sec


جریان اون ip2long ته Angel Big Grin
وبلاگ: Yousha.Blog.ir

صدام: "اگر با ارتش شاه ایران طرف بودیم، یک ماهه جنگ را می بردیم"
http://gulfnews.com/opinion/thinkers/ira...i-1.500997
  پاسخ
تشکر شده توسط :
#3
MyIsam مگه استفاده میشه الان؟!
اینم جدولام و فیلد هاش
id کلید اصلی هست و مسلما not null میشه و int هست فکر کنم این دیگه بهترین حالت باشه از نظر جنابعالی درسته ؟ Tongue
title از نوع کاراکتری ایندکس نشده
slug کاراکتری یونیک
status از نوع عددی ایندکس شده
الان ته حرف تو شده که count(field) روی myisam بهتر از count(*) هست درسته ؟
ولی مگه الان دیگه از MyISAM استفاده میکنی ؟ Big Grin

کد:
CREATE TABLE `post` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `slug` varchar(255) NOT NULL,
  `time` int(10) unsigned NOT NULL,
  `date` char(16) NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `status` tinyint(3) unsigned NOT NULL DEFAULT '1',
  `story` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `cat_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `slug` (`slug`),
  KEY `status` (`status`),
  KEY `cat_id` (`cat_id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
کد:
CREATE TABLE `tag` (
  `post_id` int(10) unsigned NOT NULL,
  `tag` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  KEY `post_id` (`post_id`),
  CONSTRAINT `tag_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

خلاصه هر تستی تو بگی من انجام میدم
یه جدول 7 میلیون رکوردی با یک جدول 50 میلیون رکوردی دستمه Big Grin

راستی صرفا جهت اطلاع دقیقا همین دیتاها روی postgresql هم هست
هارد هم ssd هست Big Grin

و شاید جالب باشه برات ، حجم دیتاهای فایل (فایل دیتابیس) روی postgresql دو برابر mysql هست mysql فکر کنم نزدیک 9 گیگ هارد برده pg نزدیک 17 گیگ
  پاسخ
تشکر شده توسط :
#4
(۱۳۹۴ اسفند ۲۲, ۰۴:۴۶ ب.ظ)Reza نوشته: MyIsam مگه استفاده میشه الان؟!
ولی مگه الان دیگه از MyISAM استفاده میکنی ؟ Big Grin

دیگه الان؟ شوخی میکنی؟ Big Grin
آره چرا که نه
مگه منسوخ شده
تا اونجایی که یادمه InnoDb مناسب دیتابیس های حجیمه، MyISAM مناسب دیتابیس های کوچیک و متوسطه (فکر کنم یکسری تاپیک هم در همین مورد توی انجمن باشه)
2016
https://support.rackspace.com/how-to/mys...vs-innodb/
http://stackoverflow.com/questions/12614...and-innodb
http://www.kavoir.com/2009/09/mysql-engi...-cons.html
http://dba.stackexchange.com/questions/1...and-myisam

بعدم من اصلاً درباره InnoDb حرفی نزدم و نظری ندارم. نمی دونم چرا اینقدر میخوای سرعت و آزمایشاتش رو ثابت کنی Big Grin
نه رد کردم و نه تایید
آون آزمایش من (چه قدیم چه جدید) درباره MyISAM هستش
InnoDb چیه این وسط Big Grin

بنظرم پست اولت رو اصلاح کن و مشخصات پلتفورم آزمایشت رو هم بنویس توش. مقایسه من و تو هیج ربطی به هم ندارن
وبلاگ: Yousha.Blog.ir

صدام: "اگر با ارتش شاه ایران طرف بودیم، یک ماهه جنگ را می بردیم"
http://gulfnews.com/opinion/thinkers/ira...i-1.500997
  پاسخ
تشکر شده توسط :
#5
نمی تونی همینجوری بگی باید پروفایلش رو بزاری. ساختار دیتابیس رو بزاری. روی id ایندکس گذاشتی یا نه؟ این نتایج منه
کد:
wms=# \timing
Timing is on.
wms=# select count(*) from avl_geodata;
  count  
---------
7838447
(1 row)

Time: 22091.258 ms
wms=# select count(id) from avl_geodata;
  count  
---------
7838447
(1 row)

Time: 17365.616 ms
wms=#
روش بنچمارک و شرایط بنچمارک باید توی شرایط یکسانی باشه. ولی به تجربه بهت میگم روی pgsql هنوز هم count(id) سرعت بیشتری داره. چون تا حدی از ایندکس استفاده می کنه
البته استفاده از count به هر طریقی روی دیتابیس های بزرگ بی معنیه و اگر هم واقعا لازم باشه از روشهای تقریبی باید استفاده کرد.
  پاسخ
تشکر شده توسط : Y.P.Y
#6
نقل قول:روش بنچمارک و شرایط بنچمارک باید توی شرایط یکسانی باشه.
Dodgy
دو تا کوئری رو روی یه سرویس به فاصله یک ثانیه تست کردن شرایط یکسان میخواد ؟!

مگه شرایطشون یکسان نیست
Dodgy

نقل قول: تا اونجایی که یادمه InnoDb مناسب دیتابیس های حجیمه، MyISAM مناسب دیتابیس های کوچیک و متوسطه (فکر کنم یکسری تاپیک هم در همین مورد توی انجمن باشه)
MyISAM اون زمانا (چون من باهاش کار نمیکنم) کلید خارجی نداشت فکر کنم ، قفل جدول نداشت فکر کنم به همین دلیل دیگه کلا من خطش زدم Big Grin

نقل قول: ولی به تجربه بهت میگم روی pgsql هنوز هم count(id) سرعت بیشتری داره. چون تا حدی از ایندکس استفاده می کنه
خب مگه count(*) از ایندکس استفاده نمیکنه !؟
[عکس: test.png]
نقل قول: البته استفاده از count به هر طریقی روی دیتابیس های بزرگ بی معنیه و اگر هم واقعا لازم باشه از روشهای تقریبی باید استفاده کرد.
اینو قبول دارم اما خب باید داده ها زیاد باشه تا تفاوت سرعتشون مشخص بشه !!!
  پاسخ
تشکر شده توسط :
#7
ببین به ساختار دیتابیست به پارتیشن بندی کردنت به ایندکس گذاریت به .... به خیلی از اینجور چیزها بستگی داره. همین که داری میگی به فاصله چند ثانیه بعدش دارم میزنم کش رو پاک می کنی؟ قاعدتا باید postgresql رو ریست کنی.
البته در کل این موضوع ها اهمیتی نداره و اینطور بهینه سازی ها فقط باید در شرایطی که مشکلی به وجود میاره و روی دیتابیس واقعی تست بشه. در یک شرایطی ممکنه count(*) بهتر جواب بده در یک شرایط دیگه count(id)
اینکه من الان بگم count * سریعتر از count id هست در هر شرایطی صادق نیست.
  پاسخ
تشکر شده توسط :


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان