Скорость обработки запросов на SQL серверах
oRs.Open();
return oRs;
}
function db_Close(){
oConn.Close();
}
function db_Requery(Rec,SQL){
Rec.Close();
Rec.Source = SQL;
Rec.Open();
}
db_Connect();
try {
oRs=db_Record("CREATE TABLE dbo.DBTEST ( String char (30) NULL, Number int NOT NULL DEFAULT (0), Random int NOT NULL DEFAULT (0))");
} catch (e) {
}
oRs=db_Record("SELECT * FROM DBTEST WHERE 0=1");
for(i=0;i<100000;i++){
oRs.Addnew();
oRs("String").value="User"+i;
oRs("Number").value=i;
oRs("Random").value=Math.round(100*Math.random());
oRs.Update();
if(i%10000==0)
WScript.echo("Now in base present "+i+" records");
}
WScript.echo("Completed");
База даних буде мати вид :
String | Number | Random |
User1 | 1 | 34 |
User2 | 2 | 12 |
User3 | 3 | 75 |
. . . . | . . . . | . . . . |
У наведеному Script функція Connect відповідає за регістрацію в SQL Server і утворення бази даних DBTest .
DSN – ім”я зв”язку, визначається при утворенні джерела даних ODBC.
UID – ідентифікатор користувача, використовується при регістрації на сервері, у SQL Server ідентифікатор користувача завжди має починатись з “ sа ” .
PWD – або “ password ” кодове слово доступу , необхідний для регістрації на сервері. В даному випадку не використовуємо.
Функція Record проводить запис у всі рядки бази даних DBTest створені значення , у стовбчик Random – створені генератором випадкових чисел значення від 0 до 99 .
Кількість рядків у таблиці буде 10 000, створення займає 3,5 хвилин. Стовбчик Number буде ключем.
Напишемо ще один Script , для тестування швидкості роботи SQL Server . Щоб визначети час відповіді на запит як умога точніше будемо посилати на сервер не один запит , а декілька десятків однакових запитів, обрахувавши середній час відповіді отримаємо точний час обробки запиту і знаходження сервером результуючої множини елементів. Але треба враховувати такий випадок - якщо для підвищення точності послати декілька сотень однакових запитів, то SQL Server почне хешування таблиці для оптимізації своєї роботи
і результати роботи будуть не точні, оскільки при звичайному запиті хешування таблиці не робиться.
// ADO Flags
var adLockOptimistic = 3;
var adOpenStatic = 3;
var SQL_DataBase = "DSN=OTSt;UID=sa;PWD=;DATABASE=OTSt"
//var SQL_DataBase = "DSN=OTStt;UID=;PWD="
var oConn;
var oRs;
function db_Connect(){
// Create ADO Connection Object. Use IISSDK OBDC Souce with
// default sa account and no password
oConn = new ActiveXObject("ADODB.Connection");
oConn.Open(SQL_DataBase);
oConn.CommandTimeout=600;
}
function db_Record(SQL){
var oRs;
// Create ADO Recordset Component, and associate it with ADO connection
oRs = new ActiveXObject("ADODB.Recordset");
oRs.ActiveConnection = oConn;
// Get empty recordset
oRs.Source = SQL;
oRs.CursorType = adOpenStatic; // use a cursor other than Forward Only
oRs.LockType = adLockOptimistic; // use a locktype permitting insertions
oRs.Open();
return oRs;
}
function db_Close(){
oConn.Close();
}
function db_Requery(Rec,SQL){
Rec.Close();
Rec.Source = SQL;
Rec.Open();
}
function Test(TestNumber, Query, CountTests){
Max=0;
Min=1000000;
Delta=0;
Ave=0;
WScript.echo("Query #"+TestNumber);
for(i=0;i
StartTime=new Date();
db_Requery(oRs,Query);
EndTime=new Date();
Delta=(EndTime-StartTime);
WScript.echo(" Probe #"+i+"
Result="+Delta+" ms");
Ave=(Ave*i+Delta)/(i+1);
}
WScript.echo(" Result="+Ave+" ms");
}
db_Connect();
oRs=db_Record("SELECT * FROM DBTEST WHERE 1=0");
Test(1, " SELECT * FROM DBTEST " , 50
);
Test(2 , " SELECT * FROM DBTEST ORDER BY
String",50);
Test( 3 ," SELECT * FROM DBTEST ORDER BY Number
",50);
Test (4,"SELECT Sum(Number) FROM DBTEST GROUP BY
String",50);
Test(5 , " SELECT Sum(Number) FROM DBTEST
GROUP BY
Random",50);
Test( 6 , " SELECT * FROM DBTEST WHERE Number
= 99999 " , 50);
Test(7 ," SELECT * FROM DBTEST WHERE String =
'User99999'",50);
Test(8,"SELECT * FROM DBTEST WHERE Number
in (SELECT
Number FROM DBTEST ) " , 50 );
Test(9 ,"SELECT * FROM DBTEST WHERE Number in
(SELECT
Number FROM DBTEST WHERE String < ' User50000 '
) ",50);
Test(10 , " SELECT * FROM DBTEST WHERE
Number in (SELECT
Number FROM DBTEST WHERE String='User50000')",
50);
Test(11, " SELECT * FROM DBTEST WHERE
Number in (SELECT
Number FROM DBTEST WHERE String > '
User10000 ' ) " , 50);
Test(12 , "INSERT INTO DBTEST
(String,Number)
VALUES('User30',30) " , 50 );
Test(13 , "DELETE FROM DBTEST
(String,Number)
VALUES('User30',30) " , 50);
Test(14 ," DELETE FROM DBTEST " , 1);
db_Close()
Головна
функція Test у
циклі 50 разів
посилає запит
на сервер,
обраховує
різницю між
початком обробки
запиту і часом
закінчення
обробки :
StartTime=new Date();
« обробка
запиту
»
EndTime=new Date();
Delta=(EndTime - StartTime);
У
останньому
script
маємо 14 тестів
для тестування
різних можли-востей
SQL
Server.
Розглянемо
їх докладніше
.
Тести
12 і 13 характеризують
швидкість
вставки
і вилучення
елементів у
базі даних.
Тест
14 знищує усю
таблицю.
Запити
на вибірку
інформації
:
Тест
1:" SELECT * FROM DBTEST " - виділити
всі елементи
;
Тест
2: " SELECT * FROM DBTEST ORDER BY String"
-відсортувати
усі елементи
за значенням
у стовбчику
“String”;
Тест
3:" SELECT * FROM DBTEST ORDER BY Number"-
відсортува-ти
усі елементи
за значенням
у стовбчику
“ Number ”;
Тест
4:"SELECT Sum(Number) FROM DBTEST
GROUP BY String"
-
скласти усі
елементи стовбчика
“ Number ” за значенням
у стовбчи-ку
“String”;
Тест
5:" SELECT Sum(Number) FROM DBTEST GROUP BY
Random" -
скласти усі
елементи стовбчика
“ Number ” за значенням
у стовбчику
“ Random ”;
Тест
6:" SELECT * FROM DBTEST WHERE Number = 99999 " –
визначити усі
елементи, у
яких значення
у стовбчику
“ Number ” = 99999;
Тест
7:" SELECT * FROM DBTEST WHERE String = 'User99999'"
- визначити
усі елементи,
у яких значення
у стовбчику
“String “ = 'User99999' ;
Тест
8 : "SELECT * FROM DBTEST WHERE Number in (SELECT
Number FROM DBTEST ) " - визначити
усі елементи
з множини чисел
;
Тест
9 :"SELECT * FROM DBTEST WHERE Number in (SELECT
Number FROM
DBTEST WHERE String < ' User50000 ' ) " - визначити
усі елементи
з множини
елементів, у
яких значення
у стовбчику
“String “ < ' User50000 ';
Тест
10 : " SELECT * FROM DBTEST WHERE Number in (SELECT
Number FROM DBTEST WHERE String='User50000')" - визначити
усі елементи
з множини
елементів, у
яких значення
у стовбчику
“String “ = ' User50000';
Тест
11 : " SELECT * FROM DBTEST WHERE Number in (SELECT
Number FROM DBTEST WHERE String > ' User10000 ' ) "-
визначити усі
елементи з
множини елементів,
у яких значення
у стовбчику
“String “ > ' User10000' ;
Частина
3 :
РЕЗУЛЬТАТИ
ТЕСТУВАННЯ
Для
наведення
прикладу
універсальності
при використанні
написан-ного
script
при вимірюванні
швидкодії,
виміряємо
швидкість
обробки запитів
у системі SQL
Server
7.0 та Microsoft
Access
97.
Щоб
script
сприймався
системою Access
без суперечень
треба змінити
параметри
ідентифікації
:
//var
SQL_DataBase = "DSN=OTSt;UID=sa;PWD=;DATABASE=OTSt"
var SQL_DataBase = "DSN=OTStt;UID=;PWD="
Отримані
результати
приведемо у
таблиці : Тест
№
Як
видно з результатів
проведенного
вимірювання
запити на
локальній базі
даних Access
опрацьовуються
значно швидше
ніж на сервері.
Аналізуючи
запити 2 і 3, 4 і
5, 6 і 7 бачимо, що
обробка елементів
різних типів
у однакових
запитах має
різний час.
Так
наприклад
сортувати
усіх елементів
за значенням
у стовбчику
“String”
опрацьовується
повільніше
ніж у стовбчику
" Number"- причина
у розміру
елементів цих
типів.
Теж
саме при обробці
запитів 4 і 5
при сумуванні
елементів
стовбчика "
Number" за елементами
стовбчиків
“ String
” і ” Random”.
Стовбчик
“String
” зберігає
значення типу
String
і стовбчик
”Random”
зберігає
значення типу
Integer,
елементи типів
мають різний
розмір і обробляються
з різною швидкістю.
Розглядаючи
швидкість
обробки множин
елментів зазначимо,
що чии більше
елементів
обробляє сервер
у базі даних
тим більше
часу на це йде.
Так наприклад
запит 10 на пошук
у базі даних
елемента типу
String
- 'User50000' ззаймає
набагато менше
часу ніж пошук
елементів,
що менше 'User50000'.
Таких елементів
приблизно 50
тисяч і їх пошук
займає досить
довгий час.
Пошук елементів,
що більше
'User10000' займає у
сервера ще
більший час.
Запити
12,13 визначають
час занесення
до бази нового
рядка і вилучення
рядка з бази
даних.
Проводячи
наведені
дослідження
за роботою
сервера ми
отримуємо
повну характеристику
його роботи.
Використаємо
наведені вище
програмні
додатки і
проведемо
виміри на інших
SQL-серверах.
Порівняємо
швидкості
роботи SQL
Server
7.0 і Oracle
8 : Тест
№
Як
видно з результатів
SQL
Server 7.0 працює швидше
за
Oracle
8 при обробці
вибірок, а при
вставці і
вилученні
елементів у
Oracle краші результати.
Це
можна пояснити
різною будовою
ядер обробки
запитів.
Проведемо
такіж заміри
і для SQL
сервера Informix.
Тест
№
По
результам
видно, що SQL
Server 7.0 працює повільніше
за Informix при обробці
простих запитів,
а при пошуку
і порівнянні
елементів
працює швидше.
На
запитах по
вставці і вилученні
елементів у
Informix
і SQL
Server
7.0 майже однакові
результати.
Таким
чином ми досягли
мети данної
роботи -
SQL Server 7.0
Access
97
1
2,673
1,81
2
7,781
5,603
3
7,356
5,211
4
8,239
7,54
5
0,903
0,494
6
0,345
0,231
7
0,390
0,287
8
11,207
7,11
9
3,843
2,53
10
0,655
0,507
11
11,469
9,816
12
0,3
0,285
13
0,31
0,22
14
55,62
34,324
SQL Server 7.0
Oracle 8
1
2,673
2,71
2
7,781
8,06
3
7,356
8,09
4
8,239
8,75
5
0,903
1,041
6
0,345
0,4
7
0,390
0,432
8
11,207
11,917
9
3,843
4,05
10
0,655
0,78
11
11,469
12,021
12
0,3
0,295
13
0,31
0,291
14
55,62
43,134
SQL Server 7.0
Informix
1
2,673
2,11
2
7,781
6,932
3
7,356
7,138
4
8,239
7,934
5
0,903
0,856
6
0,345
0,456
7
0,390
0,471
8
11,207
13,04
9
3,843
4,41
10
0,655
0,748
11
11,469
12,814
12
0,3
0,315
13
0,31
0,31
14
55,62
51,48