Personal tools
You are here: Home Статьи Тестируем ZODB на скорость
Document Actions

Тестируем ZODB на скорость

by cray last modified 2007-01-15 18:30

В статье приводится сравнение по скорости ZODB и MySQL, результаты получились, в принципе, вполне ожидаемые. Но, все-таки,\ приятно, что и в ZODB можно вставить один миллион объектов...

Сравнительное тестирование MySQL и ZODB :

Недавно в пылу полемики в одной рассылке, наш оппонент выдвинул тезис вроде такого: "ZODB это вообще не база данных, потому что в ней нельзя сохранить один миллион записей, как в MySQL". Оставив на совести оппонента определение базы данных, как того, в чем можно сохранить один миллион записей, я призадумался: "А все-таки, насколько ZODB проигрывает по скорости MySQL?", - и провел соответствующие исследования.

До того, как рассказать о результатах, замечу: ZODB и MySQL совершенно различные базы данных как по целям применения, так и по стоящей за ними модели данных:

-- ZODB оптимизирована для редких операций записи и частых операций чтения, тогда как MySQL такой оптимизации не имеет;

-- ZODB база объектно-ориентированная, MySQL - реляционная. Соответственно, в реальных условиях ZODB никогда не будет иметь такого режима работы, как MySQL, впрочем, обратное тоже верно.

Приводимый ниже тест носит поверхностный характер и борьба происходит скорее на поле MySQL, чем на поле ZODB: мы просто тестируем хранилище на скорость записи и извлечения табличных данных.

Результаты:

Для тестирования использовались:

MySQL версии 5.0.27

Zope версии 3.3.0

Вставка 1000000 записей в ZODB:

Затрачено времени: 3 часа 48 минут.

Средняя скорость вставки: 71 запись в секунду.

Длительность переупаковки базы: 3 минуты.

Объем базы: 889М до упаковки и 29М после.

Вставка 1000000 записей в MySQL:

Затрачено времени: 2 минуты

Средняя скорость вставки: 8928 записей в секунду.

Объем базы: 37М

Чтение из ZODB:

Затрачено времени: 2 минуты

Средняя скорость чтения: 7194 записей в секунду.

Чтение из MySQL:

Затрачено времени: 5 минут

Средняя скорость чтения: 3278 записей в секунду.

Заключение:

Как можно видеть, ZODB действительно притормаживает на операциях вставки (практически на два порядка), и несущественно обгоняет MySQL на операциях извлечения данных. Поэтому, использование ZODB как хранилища архивов вполне оправдано, для чего она собственно и разрабатывалась.

Впрочем, серьезное тестирование не проводилось :), поэтому за точное количественное воспроизведение результатов я не поручусь: потому и характеристики железа не привожу, что бы соблазна не было. Кроме того, сами статистические характеристики теста далеки от той реальности, в которой работает ZODB.

А по относительным данным замечу еще вот что: любим мы ZODB не за скорость. А за траспарентность при работе с данными. К сожалению, по причине отсутствия соответствующих средств в MySQL, сравнивать их на этом поле я не могу. А было бы интересно :)

Приложение А : Исходники тестов

Скриптик для записи в MySQL:

        #/usr/bin/python
        import MySQLdb
        import time
        con=MySQLdb.connect(db="test")
        con.autocommit(1)
        con.query("CREATE TABLE a(ak varchar(64), av varchar(64));")
        con.query("create index ai on a(ak);")
        t1 = t = time.time()
        for item in range(0,1000000) :
            if not item % 1000 :
                t2 = time.time()
                print item,t2-t1
                t1 = t2
            con.query("INSERT INTO a VALUES ('%s','%s');" % (item,item))        

        print "Time:",time.time()-t

        con.close()

     Скриптик для записи в ZODB::

        #/usr/bin/python
        import ZODB
        import time
        from ZODB.FileStorage import FileStorage
        from  BTrees.OOBTree import OOBTree
        d=ZODB.DB(FileStorage("/tmp/d.fs"))
        con=d.open()
        con.root()['btree'] = OOBTree()
        import transaction
        txn=transaction.get()
        txn.commit()

        t1 = t = time.time()
        for item in range(0,1000000) :
            if not item % 1000 :
                t2 = time.time()
                print item,t2-t1
                t1 = t2

            con.newTransaction()
            con.root()['btree'][str(item)] = str(item)
            txn=transaction.get()
            txn.commit()
        print "Time:",time.time()-t
        d.pack()
        print "Time:",time.time()-t
        con.close()
        d.close()

Скриптик для чтения MySQL:

        #/usr/bin/python
        import MySQLdb
        import time
        con=MySQLdb.connect(db="test")
        con.autocommit(1)
        t1 = t = time.time()
        for item in range(0,1000000) :
            if not item % 1000 :
                t2 = time.time()
                print item,t2-t1
                t1 = t2
            cur=con.cursor()
            cur.execute("SELECT av FROM a WHERE ak='%s';" % item)        
            cur.fetchall()

        print "Time:",time.time()-t

        con.close()

Скриптик для чтения ZODB:

        #/usr/bin/python
        import ZODB
        import time
        from ZODB.FileStorage import FileStorage
        from  BTrees.OOBTree import OOBTree
        d=ZODB.DB(FileStorage("/tmp/d.fs"))
        con=d.open()
        import transaction
        txn=transaction.get()
        txn.commit()

        t1 = t = time.time()
        for item in range(0,1000000) :
            if not item % 1000 :
                t2 = time.time()
                print item,t2-t1
                t1 = t2

            con.newTransaction()
            a=con.root()['btree'][str(item)]
            txn=transaction.get()
            txn.commit()
        print "Time:",time.time()-t

        con.close()
        d.close()


Powered by Plone CMS, the Open Source Content Management System