Showing posts with label ms sql server. Show all posts
Showing posts with label ms sql server. Show all posts

Wednesday, August 5, 2009

MySQL and MS SQL Server

Recently, MySQL had an article comparing MySQL and SQL Server at  http://dev.mysql.com/tech-resources/articles/move_from_microsoft_SQL_Server.html

There is one clarification I would like to make to this article.  The article states that MS SQL Server has row locking, and while this is true, MS SQL Server doesn’t always use row locking and often will resort to page locking.  A page is 8k of data, so, in effect, many rows are locked at the same time even if only one row in that page is being updated.  At high data throughputs, this can lead to serious lock contention and to dead locks, even though the two processes with the contention or dead  lock are updating different rows.   Stated differently, no matter how well you order your multi-row update processes in MS SQL Server you should expect deadlocks. 

There is a way to turn off page locks on an index, but a index can’t be reorganized if page locks are off as index reorganization uses page locks.   Alternatively, one can add a row lock hints to each SQL statement, but this becomes tiresome fast.  The general approach to this problem is to keep each transaction small, smaller than you perhaps want, which reduces but doesn’t eliminate the page lock contention and dead locks.  

Easy to use with sensible defaults, MS SQL Server is a great database;  but page locking is a relic from the past when row locks consumed too much of that rare  memory.  In the 64 bit processor world, memory is too plentiful to worry about how much memory row locks take and page locks hurt scalability.   As more recent database design, the MySQL model of only using row locks makes far more sense. 

Friday, February 13, 2009

Are MySQL stored procedures slow?

 

Yes, if compared to code in Java or C#. For example, this overly simple code took 284 seconds.

CREATE PROCEDURE CountTest()
begin
    declare counter int default 0;
    select now();
    repeat
        set counter = counter + 1;
    until counter > 120000000
    end repeat;
    select counter;
    select now();
end

Ignoring my off by one error, here is equivalent code in C# (the language I’m currently learning).  It took 419 milliseconds, or MySQL took 677 times longer to execute. From my experience, Java isn’t going to be any slower.

 int counter = 0;
while (counter < 120000000)
{
    counter++;
}

Slow stored procedure performance is one of the reasons why it usually isn’t wise to implement computationally expensive business logic in the database.   With networks not being the bottleneck they once were it is often better to extract the data to the application layer and process it in the programming language of your choice, even if that takes a few extra round trips to the database.  There are exceptions where those extra round trips are too numerous and prohibitively expensive.  With something as complex as a database there are always exceptions.

This example is a bit too simple, but, based on experience, it is representative of the general performance of stored procedure logic.

How can MySQL get away with such poor performance? Well, the equivalent code in MS SQL Server took 80 seconds on the same hardware, which is also two orders of magnitude slower than C# or Java code. 

create procedure testCount
as
begin
    declare @countNo int;
    set @countNo = 0;
    while (@countNo < 120000000)
    begin
        set @countNo = @countNo + 1
    end
    select @countNo
end

MS SQL Server code runs 3.5 times faster than MySQL, but given how much older MS SQL Server is, MySQL is doing well here.  So are MySQL Stored procedures slow?  Not really, if compared to other databases I’ve used.

Just don’t use them to do computationally expensive business logic.