бавно та бавно

12 отговора 0 прегледа
#1

бавно та бавно

Глейте сега имам едни заявки, които варвят ама отнемат 100 години:

# xsql "show processlist;"
Database name not supplied. Using UNInventory.
Executing:
show processlist;
quit
=====================
+-----+------+-----------+-------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+------+-----------+-------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| 155 | root | localhost | UNInventory | Query | 2967 | Sending data | update equip t, equipment s, rack r
set t.rack=r.id
where t.name=s.Device_name
and s.Floor=r.floo |
| 158 | root | localhost | UNInventory | Query | 0 | NULL | show processlist |
+-----+------+-----------+-------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+

самата заявка е тази:
update equip t, equipment s, rack r
set t.rack=r.id
where t.name=s.Device_name
and s.Floor=r.floor
and s.Room_no=r.room
and s.Rack_location=r.rack;

екуипмент е заредена от един плосък фаил и се опитвам да нормализирам съдържанието и в екуип като изнеса повтарящата се информация за раковете в които са монтирани серверите в отделна таблица към която екуип да има форин кий.

екуипмент и екуип имат равен брой записи -- около 2500 а раковете са под 400 (379).

Та не виждам що тоя упдейт трябва да отнема близо 1 час.

сервера на който рънвам е SLES_9 , хардуера е ProLiant_DL380_G3 със 6 ГБ памет

версията на майскюл е:
xsql "select version();"
Database name not supplied. Using UNInventory.
Executing:
select version();
quit
=====================
+-----------+
| version() |
+-----------+
| 5.0.18 |
+-----------+

Благодаря за очакваните (от вас) съвети и идеи.

Очеввидно това денормализиране ще се прави само веднъж, така че бавността
не е фатална, ама нали трябва и да се тества и изобщо от чисто любопитсво що трябва да е толкова бавно?

Редактирано от bjLubo на

Отговор
в отговор на bjLubo #2

Re: бавно та бавно

нещо не ми харесва самата заявка за update

Отговор
в отговор на bjLubo #3

Re: бавно та бавно

Я дай

EXPLAIN SELECT t.name, s.Device_name, s.Floor, s.Room_no, s.Rack_location, r.floor, r.room, r.rack FROM equip t, equipment s, rack r WHERE t.name=s.Device_name and s.Floor=r.floor and s.Room_no=r.room and s.Rack_location=r.rack;

и SHOW CREATE TABLE на трите таблици

salle.online.bg/sig
Отговор
в отговор на salle #4

show create table equipment;

| equipment | CREATE TABLE `equipment` (
`Status` varchar(20) default NULL,
`Device_Type` varchar(20) default NULL,
`Mfg_Name` varchar(20) default NULL,
`Mfg_Model` varchar(20) default NULL,
`Floor` varchar(20) default NULL,
`Room_no` varchar(20) default NULL,
`Rack_Location` varchar(20) default NULL,
`Server_Location` varchar(20) default NULL,
`Serial_no` varchar(20) default NULL,
`DiskSpaceLocal` varchar(20) default NULL,
`DiskSpaceSan` varchar(20) default NULL,
`First_IP` varchar(20) default NULL,
`Assign_To` varchar(20) default NULL,
`Primary_Contact` varchar(20) default NULL,
`Secondary_Contact` varchar(20) default NULL,
`OS` varchar(20) default NULL,
`OS_Version` varchar(20) default NULL,
`Apps` varchar(20) default NULL,
`DNS_Entry` varchar(20) default NULL,
`Device_Name` varchar(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |


ili za po-iasno:
cat equipment.tbl
. /ddl/.dotin
INF=/ddl/inv.in
T=equipment

xsql "
drop table if exists $T;
CREATE TABLE $T (
Status varchar(20)
,Device_Type varchar(20)
,Mfg_Name varchar(20)
,Mfg_Model varchar(20)
,Floor varchar(20)
,Room_no varchar(20)
,Rack_Location varchar(20)
,Server_Location varchar(20)
,Serial_no varchar(20)
,DiskSpaceLocal varchar(20)
,DiskSpaceSan varchar(20)
,First_IP varchar(20)
,Assign_To varchar(20)
,Primary_Contact varchar(20)
,Secondary_Contact varchar(20)
,OS varchar(20)
,OS_Version varchar(20)
,Apps varchar(20)
,DNS_Entry varchar(20)
,Device_Name varchar(20)
) ;
"

xsql "
load data INFILE '$INF' into TABLE $T
FIELDS TERMINATED BY '|';
"

Отговор
в отговор на salle #5

show create table equip

| equip | CREATE TABLE `equip` (
`id` int(10) NOT NULL auto_increment,
`tid` int(4) default '0',
`gid` int(4) default '0',
`status` int(4) default '0',
`name` varchar(40) default NULL,
`sn` varchar(30) default NULL,
`os` int(4) default '0',
`rack` int(4) default '0',
`mid` int(4) default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |

ili za po-iasno:
xsql "
drop table if exists equip;
CREATE TABLE equip (
id int(10) NOT NULL auto_increment,
tid int(4) default 0,
gid int(4) default 0,
status int(4) default 0,
name varchar(40) default NULL,
sn varchar(30) default NULL,
os int(4) default 0,
rack int(4) default 0,
mid int(4) default 0,
PRIMARY KEY (id)
) ;"
echo "Table created at $(date)"
xsql "
insert into equip (tid, status, name,sn)
select t.id, s.id, e.Device_Name, e.Serial_no
from equipment e, status s, type t
where e.Status!=''
and e.Device_Name!=''
and e.Status=s.name
and e.Device_type=t.name ;
"
echo "Initial insert done at $(date)"
xsql "
update equip t, equipment s, rack r
set t.rack=r.id
where t.name=s.Device_name
and s.Floor=r.floor
and s.Room_no=r.room
and s.Rack_location=r.rack;
"
echo "Rack/datacenter done at $(date)"

Отговор
в отговор на salle #6

show create table rack;

| rack | CREATE TABLE `rack` (
`id` int(11) NOT NULL auto_increment,
`center` varchar(40) default NULL,
`floor` char(6) default NULL,
`room` char(8) default NULL,
`rack` char(10) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |


ili za po-iasno:
T=rack
xsql "
drop table if exists $T;
CREATE TABLE $T (
id int(11) NOT NULL auto_increment,
center varchar(40) default NULL,
floor char(6),
room char(8),
rack char(10),
PRIMARY KEY (id)
) ;
insert into $T (center, floor, room, rack)
select distinct concat(Floor,Room_no),
Floor, Room_no, Rack_Location
from equipment ;
"

Отговор
в отговор на salle #7

explain

Executing:
explain select t.name, s.Device_name, s.Floor, s.Room_no, s.Rack_location, r.floor, r.room, r.rack
from equip t, equipment s, rack r
where t.name=s.Device_name
and s.Floor=r.floor
and s.Room_no=r.room
and s.Rack_location=r.rack;

quit
=====================
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | r | ALL | NULL | NULL | NULL | NULL | 379 | |
| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 1292 | |
| 1 | SIMPLE | s | ALL | NULL | NULL | NULL | NULL | 2477 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

Отговор
в отговор на AйeзCeдaй #8

Re: бавно та бавно

Mi predloji po-iak update:

Equipment e denormalizirane i съдържа vsi4ko

equip съдържа serverite (serial number i name) ot equipment

rack съдържа distinct racks ot equipment kato na vseki rack e присвоен autoincrement id

Целта е на натикам ж екуип ид-тата на раковете

(сори, бях забравил че имам кирилица на тоя компютър)

Отговор
в отговор на bjLubo #9

Re: бавно та бавно

Популирай първо rack и после на самия INSERT в equip обзаведи FK-я така например:
insert  equip (tid, status, name, sn, rack)

select (SELECT id FROM type WHERE name = e.Device_type)
, (SELECT id FROM status WHERE name = e.Status)
, e.Device_Name
, e.Serial_no
, (SELECT id FROM rack WHERE floor = e.Floor AND room = e.Room_no AND rack = e.Rack_Location)
from equipment e
where e.Status!=''
and e.Device_Name!=''

В случая sub-select-ите ще са по-бързи от JOIN-овете понеже не личи да имаш UNIQUE индекси на сателитните таблици. Ако имаше UNIQUE по колоните във WHERE клаузите на sub-select-ите по-горе -- id за status и type, (floor, room, rack) за rack -- това щеше да гарантира, че JOIN-овете в твоята заявка няма да "разперят" резултата, т.е. в резултата ще има <= редове от редовете на equipment.

Така със sub-select-и това става очевидно за db engine-а -- просто във FROM клаузата има само една таблица!

cheers,
</wqw>

[линк]
Отговор
в отговор на wqw #10

Re: бавно та бавно

Tуй е интересно и ще го опитам при първа възможност -- благодаря.
Междувременно сложих индекси на екуипмент и екуип:
create index name_ind on equipment (Device_name, Status);
create index name_ind on equip (name, status);

и сега 4-те упдейта вървят за около 5 секунди:
Initial insert done at Wed Apr 9 12:35:30 EDT 2008
Dept/App set (updated) done at Wed Apr 9 12:35:32 EDT 2008
OS set (update) done at Wed Apr 9 12:35:34 EDT 2008
Rack/datacenter done at Wed Apr 9 12:35:38 EDT 2008
Model done at Wed Apr 9 12:35:41 EDT 2008

Отговор
в отговор на bjLubo #11

Re: бавно та бавно

За 2500 реда пак е смешно бавно, но щом си се оправил.

cheers,
</wqw>

[линк]
Отговор
в отговор на bjLubo #12

Re: explain

type = ALL означава, че се претърсва цялата таблица. В случая и трите таблици открай докрай. И нищо чудно след като нямаш никакви индекси в нито една таблица освен PRIMARY KEY

Индексирай всичко което се появява във WHERE клаузата и пробвай пак.


Дали отделни индекси по всяка колонка ще са по.добре от комбинирани за equimpent и rack не е ясно така, че може да се наложи да пробваш и да помислиш и за другите заявки.

salle.online.bg/sig
Отговор
в отговор на salle #13

Re: explain

мерси, така и направих -- виж отговора ми до wqw

Отговор