Əsas səhifə > Performance tests and tips > İP adreslərin düzgün şəkildə saxlanılması (performance test)

İP adreslərin düzgün şəkildə saxlanılması (performance test)

Bu yazı şəxsi araşdırmam və tapıntımdan ibarət olub mənim özümə də çox böyük zövq vermək üzərədir.
Yazıda İP adreslərin 2 yolla cədvəldə saxlanılması və bu 2 yolun performance fərqlərindən danışılacaq.
İlk öncə nümunə 2 cədvəlimizi yaradaq :

create table ip_int(
ip int unsigned not null
);


create table ip_varchar(
ip varchar(15) not null
);

1ci cədvəldə biz İP-ni integer kimi 2-ci cədvəldə isə string kimi saxlayacıq.
SUAL: İP adres 127.255.255.255 kimi bir şeydir tərkibində nöqtələr var. bunu integer kimi necə saxlamaq olar ki?
CAVAB: Bunun üçün MySQL-də xüsusi 2 funksiya vardır. function_inet-atonfunction_inet-ntoa

Və yuxarıdakı 2 cədvəlimizin hər birinə 1 milyon İP insert edək. Bunun üçün də xüsusi 2 procedure yazdım ki iş rahat olsun.

delimiter //
CREATE PROCEDURE insert_ip_int()
BEGIN 
 	SET @ip='127.255.255.255'; 
 	SET @counter=1;
	insert_loop: LOOP 
		IF (@counter>1000000) THEN 
		LEAVE insert_loop; 
		ELSE
        INSERT INTO ip_int(ip) VALUES(INET_ATON(@ip)); 
		  SET @counter=@counter+1; 
		END IF; 
	END LOOP insert_loop; 
END //

-----------------------------------------------------------------------------

delimiter //
CREATE PROCEDURE insert_ip_vacrhar()
BEGIN 
 	SET @ip='127.255.255.255'; 
 	SET @counter=1;
	insert_loop: LOOP 
		IF (@counter>1000000) THEN 
		LEAVE insert_loop; 
		ELSE
        INSERT INTO ip_varchar(ip) VALUES(@ip); 
		  SET @counter=@counter+1; 
		END IF; 
	END LOOP insert_loop; 
END //

Performance test 1 :İnsert speed:
ip_int cədvəlinə 1 milyon sadə insert:

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> call insert_ip_int();
Query OK, 0 rows affected (40.99 sec)

mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)

ip_varchar cədvəlinə 1 milyon sadə insert:

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> call insert_ip_vacrhar();
Query OK, 0 rows affected (48.02 sec)

mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)

integer şəklində insert təqribən 8 saniyə daha sürətlidir. Bilənlər bilir ki 0.001 saniyənin belə qiyməti çoxdu😉

Performance test 2 :The Total MB:
2 cədvəlin disk-də nə qədər yer tutduğuna baxaq:

SELECT  
TRUNCATE((data_length+index_length)/1024/1024,4) AS total_mb
FROM information_schema.`TABLES`
WHERE `TABLE_SCHEMA`='my_test' AND `table_name`='ip_int';

ip_int: 29.5625

SELECT  
TRUNCATE((data_length+index_length)/1024/1024,4) AS total_mb
FROM information_schema.`TABLES`
WHERE `TABLE_SCHEMA`='my_test' AND `table_name`='ip_varchar';

ip_varchar: 41.5625

41.5625 MB – 29.5625 MB = 12 MB. və yenə də əgər bir cədvəl digərindən daha yüngüldürsə demək ki query-si də daha sürətlidir.

Performance test 3 :SELECT * without index:
İndi isə hər 2 cədvələ select * verib sürətinə baxacıq. İndiki halda index-dən istifadə etmirik.

mysql> SELECT * from ip_int;
1000000 rows in set (0.77 sec)


mysql> SELECT * from ip_varchar;
1000000 rows in set (0.85 sec)

0.08 saniyə daha sürətlidir.

Performance test 4 :SELECT * with index:
İndi isə index-ləyib select verək:

select * from ip_int; 
1000000 rows in set (0.70 sec)

select * from ip_varchar;
1000000 rows in set (0.80 sec)

0.1 saniyə daha sürətlidir.

Performance test 5 :ALTER table speed:

alter table ip_int add index(ip);
Duration for 1 query: 5.119 sec.

alter table ip_varchar add index(ip); 
Duration for 1 query: 7.283 sec.

2.64 saniyə daha sürətlidir.

Nuş olsun😉

  1. Emin
    Mart 14, 2013 tarixində, saat 11:05

    Tesekkurler yaziya ve etrafli muqayiselere gore. men 1 ci tipden istifade edirdim. ama int(11) secirdim tipini. siz ise int unsigned qeyd etmisiz. bunun ferqi nedir?

  2. Mart 14, 2013 tarixində, saat 11:12

    int unsigned mənfi ədədlərin daxil edilməsinin qarşısını alır.
    və əgər İNT default yəni signed olaraq: 2147483647 max ədəd tutursa unsigned kimi onun diapazonu böyüyür və 4294967295 olur. Sanki unsigned yazdıqda ədədin mənfi tərəfi gəlir müsbət tərəfinin üzərinə və dolayısı ilə daha çox sahə ayrılır.

    Unsigned qoymaqda digər bir səbəb ondan ibarətdir ki , inet_aton() və inet_ntoa() funskiyaları bunu tələb edirlər.

  3. Emin
    Mart 14, 2013 tarixində, saat 19:20

    aha.aydindi. ama men ip ni bazaya yazmamisdan evvel inet_aton() ve inet_ntoa() funksiyalarinin php de olan evezleyicilerini, ip2long() ve long2ip() istifade edirem.

    ve birdeki inet_aton() funksiyasinnan kecmis ip adres menfi eded ala bilmez? ama azercelin 217.168.185.36 ip adresini kecirende -643253980 alinir axi

  4. Mart 14, 2013 tarixində, saat 19:48

    men bilmədim siz mənfi ədədi necə aldınız ama məndə müsbətdir göstərdiyiniz İP adresi yoxladım:

    mysql> select inet_aton(‘217.168.185.36’);
    +—————————–+
    | inet_aton(‘217.168.185.36’) |
    +—————————–+
    | 3651713316 |
    +—————————–+
    1 row in set (0.00 sec)

    mysql> select inet_ntoa(‘3651713316’);
    +————————-+
    | inet_ntoa(‘3651713316’) |
    +————————-+
    | 217.168.185.36 |
    +————————-+
    1 row in set (0.00 sec)

  5. Emin
    Mart 14, 2013 tarixində, saat 20:02

    php nin ip2long() funksiyasinin sehfidir nese. bele yazanda sizde alinan netice ile eyni olur

    echo sprintf(‘%u’, ip2long(‘217.168.185.36’));
    netice: 3651713316

    Tesekkurler bir daha izaha gore

  6. Mart 14, 2013 tarixində, saat 20:14

    Məncə MySQL-in öz funksiyası daha gözəldir😉
    Dəyməz sizə də aktiv iştirak və istifadə üçün təşəkkürlər….

  1. No trackbacks yet.

Bir cavab yazın

Sistemə daxil olmaq üçün məlumatlarınızı daxil edin və ya ikonlardan birinə tıklayın:

WordPress.com Loqosu

WordPress.com hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

Twitter rəsmi

Twitter hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

Facebook fotosu

Facebook hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

Google+ foto

Google+ hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

%s qoşulma

%d bloqqer bunu bəyənir: