воскресенье, сентября 17, 2006

Finally we are here :)


Bye-bye Moscow, hello Phoenix!

This was an amazing trip - 12 hours to Atlanta, 3 hours at the Hartsfield-Jackson Atlanta International Airport, 4 hours to Phoenix, and we are here. Thanks Tony for picking us up! First impressions: very hot, very clean, very polite people :) Reluctant to write, see photos :)



At the baseball game - amazing show :)
From left to right - Igor, Noah, Anton, and I - Vladislav Scherbinin!








Quite strange building - like a punchcard.















C'mon braza :)







Another great view.
Small cosy bar.

Tony was (and actually is :) ) so kind and took us to the shopping .

четверг, сентября 07, 2006

Yet another one myth about clustered index in MS SQL 2k

So, there are many myths about clustered index. One of them is that when clustered index exists on the table, databse engine doesn't use IAM pages anymore to retrieve data, it uses doubly-linked list of pages. Also one of my favorite authors - Khen Henderson mentioned about that. This is partially true. I've found that in the read uncommitted isolation level, SQL Server still uses IAM to retrieve data. Here is the repro:

create database test
go
use test
go
drop table dbo.test
go
create table dbo.test (
i int primary key clustered identity(1, 1),
d int
)
go
insert into dbo.test (d)
select top 100000 checksum(newid()) from master..sysobjects s1, master..sysobjects s2, master..sysobjects s3
go

select * from dbo.test with(readuncommitted)
Clustered index scan, the result is:
3328 -1892742514
3329 -1303737718
3330 -1030174007
3331 -157548677
3332 1160183127
98533 -1095189775
98534 -1661674379
98535 -1640363165
98536 1313858725
98537 -271346219

select * from dbo.test
Clustered index scan, the result is :
3328 -1892742514
3329 -1303737718
3330 -1030174007
3331 -157548677
3332 1160183127
3333 -1669536656
3334 -327094669
3335 -1424229963
3336 -923814371
3337 655524158

Why so? Why we've got unsorted result in the first case (I know about ordering guaranties and so on, I'm speaking about different thing)? Let's go more deeply.

dbcc traceon(3604)
go
declare @db_id int, @tbl_id int
select @db_id = db_id('test'), @tbl_id = object_id('test')
dbcc tab (@db_id, @tbl_id)

PageFID PagePID IAMFID IAMPID ObjectID IndexID PageType IndexLevel NextPageFID NextPagePID PrevPageFID PrevPagePID
------- ----------- ------ ----------- ----------- ------- -------- ---------- ----------- ----------- ----------- -----------
1 25 NULL NULL 2073058421 1 10 0 0 0 0 0
1 15 1 25 2073058421 1 2 0 0 0 0 0
1 28 1 25 2073058421 0 1 0 1 29 0 0
1 29 1 25 2073058421 0 1 0 1 30 1 28
1 30 1 25 2073058421 0 1 0 1 31 1 29
1 31 1 25 2073058421 0 1 0 1 33 1 30
1 33 1 25 2073058421 0 1 0 1 34 1 31
1 34 1 25 2073058421 0 1 0 1 35 1 33
1 35 1 25 2073058421 0 1 0 1 1704 1 34
1 1616 1 25 2073058421 0 1 0 1 1617 1 1631
1 1617 1 25 2073058421 0 1 0 1 1618 1 1616
1 1618 1 25 2073058421 0 1 0 1 1619 1 1617


Let's examine the page 1616:
dbcc page('test', 1, 1616, 3)

Slot 0 Offset 0x60
------------------
Record Type = PRIMARY_RECORD
Record Attributes = NULL_BITMAP
6B906060: 000c0010 000180e5 beb8baf1 000002 ...............
i = 98533
d = -1095189775

It is here!!! So, as you see, database engine still uses IAM to retrieve data like in the case of a heap.

My Birthday!

Ok, enough tech notes :) Tomorrow is my birthday! I hope I'll get much fun and no headache :)

Bug in MS SQL 2k in the backup/restore subsystem

Hi All! Another tech note on MS SQL. During testing of SP4 for MS SQL 2k I've found the bug in such critical place as backup/restore subsystem - if you put a database into readonly mode and then backup up the log, you'll be unable to restore this log at some point of time or savepoint - database will come into 'suspected' state. This bug also exists in the previous versions of MS SQL 2k. It is not fixed yet. Guys from MS let me to share this info. So, here is the repro (don't run it if you already have a database named 'x'!!!):
set nocount on
go
drop database x
create database x
go
backup database x to disk='c:\x.bak' with format
use x
create table t1 (id int,c1 char(4100))
go
declare @id int
select @id = 1
while @id <= 100
begin
insert into t1 values (@id,'junk')
select @id = @id + 1
end
go
backup log x to disk='c:\x.log.bak' with format
go
declare @id int
select @id = 1
while @id <= 100
begin
insert into t1 values (@id,'junk')
select @id = @id + 1
end
go
begin tran deltran with mark
delete from t1
commit
go
alter database x set read_only
go
backup log x to disk='c:\x.log.bak' with no_truncate
go
use master
go
drop database x
go
restore database x from disk='c:\x.bak' with norecovery
restore log x from disk='c:\x.log.bak' with norecovery
go
restore log x from disk='c:\x.log.bak' with file=2,recovery,stopbeforemark='deltran'
go
dbcc checkdb ('x') with no_infomsgs
go
select count(*) from x..t1
go
select * from x..t1
go

среда, сентября 06, 2006

Windows Server 2003 Inside Out in Russian!


Yet another good news for readers, who like good books :) Recenlty publishing house "Piter" issued another excellent book by William R. Stanek - Windows 2k3 Inside Out, and I participated in it's translation :) You are still here??!!! Run and buy it!!!
http://www.piter.com/book/978546901005



Here is another my translations:
Guru's Guide to Transact SQL by Ken Henderson
http://www.piter.com/book/978546900257/
Guru's Guide to SPs, HTML & XML by Ken Henderson
http://www.piter.com/book/978546900046/
OOP Demystified by Jim Keogh, Mario Giannini
http://www.piter.com/book/978546900462/

And coming soon :)
Cost-based Oracle Fundamentals by Jonathan Lewis
Analysis Services 2k5 by Irina Gorbach, Alexander Berger, Edward Melomed, Py Bateman

TOP 10 THINGS I HATE ABOUT SQL SERVER

Ok, it is time for some tech notes and maybe some fun :)
Recently I've translated this article, I really enjoyed it :) Here is the link for English speakers: http://weblogs.sqlteam.com/jeffs/archive/2005/05/24/5248.aspx
So, here is translation. Enjoy :) If you have any questions don't hesitate to contact me.

10 наиболее веских причин, почему я ненавижу SQL Server!

1. SQL слишком сложный!
Если у меня есть множество значений в моих столбцах, например "ЯНВАРЬ, ФЕВРАЛЬ, МАРТ" или "15,84,22" , это не волнует SQL Server. Практически невозможно писать операторы SQL для таких таблиц! Если я захочу получить хотя бы какие-нибудь данные, придется написать оператор SELECT из 500 строк!! За каким? И к тому же понадобится божественное вмешательство, чтобы удалить какое-нибудь значение из этих списков. Зачем MS настолько все усложняет?

2. Преобразования типов данных!
Что за фигня с преобразованием данных? Я просто использую VARCHAR для всего, так как это единственный способ избежать тупых сообщений об ошибках при добавлении данных в мои таблицы. Работает отлично, пока мне не требуется получить месяц из даты или сложить два числа - тупой SQL Server заставляет меня сначала использовать функцию convert() для преобразования значений. Что за тупизм? SQL не знает как сложить "12" и "5" - он считает, что получится "125" !!!! И чтобы все еще ухудшить, в половине случаев SQL Server выдает мне ошибки, которые говорят, что он НЕ МОЖЕТ ВЫПОЛНИТЬ ПРЕОБРАЗОВАНИЕ! Блин, если бы я был компьютером, я бы смог до этого допереть.

3. Ёпрст, что с форматированием?
Все мы с этим сталкивались: хочу выровнять по правому краю столбец в своем SELECT'е - этого нельзя сделать, не вспотев! Ни говоря уже о том, чтобы отцентрировать, сделать отступы, вставить номера страниц, или что типа того. К тому же, сплошное мученье - отформатировать даты или округлить числа как я хочу. Я с трудом могу создать нормально выглядящий отчет в Query Analyzer, он выглядит как древние файлы MS-DOS! Может пора уже перейти в 21-й век, и включить какую-нибудь поддержку графики, цвета и шрифтов, эй вы, там, в Microsoft?

4. А что с сортировкой?
В половине случаев мои записи возвращаются БЕСПОРЯДОЧНО! Да, да, они вообще не отсортированы! Это бред. SQL Server должен понимать, что все должно быть отсортировано по имени/фамилии или по дате, без всякого напоминания! Компьютеры вроде бы умные, так ведь? Мои пользователи ненавидят это, потому что им сложно ориентироваться в своих отчетах. Если они жалуются, я просто говорю им, "Блин, если бы вы не были такими скупыми, и у нас был бы Oracle, нам не пришлось бы возиться с этой "особенностью" Microsoft!"И чтобы все еще ухудшить, когда я пытаюсь отсортировать, SQL Server считает, что "Декабрь" идет перед "Январем", или, что "10" меньше "2"! Блин, господин Гейтс, уже не удивляет, что вы никогда не выпускаете свои продукты в срок, так еще и ваши парни не в курсе, как работает календарь!

5. Оператор IN() вообще никогда не работает!
Это меня бесит. Конструкция IN (@Var) никогда не работает правильно! Я никогда не получаю то, что я хочу, даже если @Var точно содержит нормальный список идентификаторов. И вы даже не получите сообщение об ошибке!

6. Ограничения внешних ключей!
По каким-то причинам, в SQL вы можете обновлять или добавлять записи только в одну таблицу за раз! Я могу написать свои обычные FULL OUTER JOIN'ы и сдуреть от SELECT'а, который выполняется весь день, но что на счет того чтобы эта штука работала в UPDATE'ах и INSERT'ах!? Как по-другому сделать ссылочную целостность? Если запись в таблице A должна соответствовать записи в таблице B, то как, черт возьми, мне их запихнуть туда одновременно? По-моему это очень глупо.

7. Первичные ключи не работают!
Я дурею от этого. У меня есть первичный ключ identity под названием "ID" у каждой таблицы, но я все равно получаю дублирующиеся данные! Я должен иметь 20 разных записей для Бобруйска в моей таблице "tblStatesTable"! Тогда в чем смысл первичных ключей? Я надеюсь в следующем сервис-паке это будет исправлено.

8. S-Q-L - Т-О-Р-М-О-З!!!
Почему SQL такой медленный? Например, чтобы найти все данные в моей таблице для Января, я использую
WHERE LTRIM(tblTable.tblTable_colMonthList) LIKE '%Янв%'
Довольно стандартная конструкция. Но она выполняется ВЕЧНО! А столбец индексирован!! Эй, вы, там, в Micro-тормозе, вообще-то индексы нужны для ускорения!

9. Загадочные сообщения об ошибках!
Значит, я пытаюсь добавить данные в таблицу, и вот что получаю:
INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK_Order_Details_Orders'. The conflict occurred in database 'Northwind', table 'Orders', column 'OrderID'. The statement has been terminated.
Или я пытаюсь написать простой GROUP BY, и получаю вот что:
Column 'orders.OrderID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Или иногда я делаю обалденные динамические запросы, но они, похоже, не работают, и я получаю:
You are not allowed to truncate the system table 'master..sysobjects'.
Ээээй? Может расскажете, что не так, вместо того, чтобы писать длинные непонятные сообщения на языке мумбо-юмбо. Господин, Билл Гейтс, может, стоит потратить немного баксов на то, чтобы в SQL Server не было багов, вместо того, чтобы писать все эти дурацкие сообщения об ошибках! У кого есть время на то, чтобы вникать в эту чушь?

10. Ссылки на таблицы и столбцы!
Это вообще бред. Значит, у нас есть умные компьютеры, так? И у нас есть что-то под названием "переменные", так? В этих переменных мы можем хранить все что угодно, даже названия столбцов и таблиц. Но вот это вообще не работает:
Select @TableName.@ColumnName from @TableName
И мне понятно, и вам понятно, я не пойму, почему это не понятно SQL Server'у! Как получить данные из таблицы 'tblCustomerNumber0121' вместо таблицы 'tblCustomerNumber0122', или получить данные из столбца 'Янв2005', если я не могу использовать переменные в такой конструкции!? Это надо делать хард-кодом!? Как, черт возьми, я должен писать отчеты с пользовательскими параметрами, если я ограничен заранее определенными названиями таблиц и столбцов!? Ну же, Micro-тупость, что на счет ДЕЙСТВИТЕЛЬНО НУЖНЫХ вещей для программирования в T-SQL, например ПОЛНОЙ поддержки переменных! К тому же на, самом деле, очень тяжело добавлять новые данные в таблицы. INSERT? Он никогда не работал! INSERT не может даже добавить новый столбец в таблицу! Как предполагается добавлять данные для нового месяца, если у меня вообще еще нет этого столбца? Может это, наконец, сделают в SQL Server 2005.

Rafting at the Altay Mountains


Here are some photos from rafting on rivers in the Altay Mountains.

The Middle Katun last summer. 4th category (from 6), pure adrenaline :) After fall over in the rift Shabash (the most powerful rift on the Middle Katun), thanks God no harm was done.



River Kumir, rift "Devichiy ples" (third category, I'm the left stroke-oarsman).
The Altay Mountains is the greatest place in the world :)

Arizona awaiting me :)

On september 11 I'll go to Phoenix, Arizona. This date slightly frighten me :) Keep your fingers crossed!

P.S. New pics coming soon.

My workplace


Hi All!

Here is my workplace at the Ajilon Consulting.