Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 3, 2015 22:30:11

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Массовый update

neitro
1. Не увидел здесь алхимию хотя смотрел в оба глаза.
2. Почему-бы перед тем, как обновить не проверить: а изменилось ли вообще поле?
3. Ну и индескы. Хотя об этом уже сказали. И не раз.
4. Sqlite хорош для малого хранения данных. Для чего-то сложнее нужно выбирать между PostgreSQL и Mongo (зависит от структуры данных). Учитывая Ваши данные предпочтительнее PostgreSQL.

P.S. Насчет 10кк реально не заметил. Но учитывая, что мной обновляемая БД структурно сложнее в разы и там огромное количество сложных проверок, то все равно у Вас очень много. Когда-то делал так-же без проверки. Разница была на проверяемой БД 25 и 7 сек. Так что имеет смысл все же проверить поле на изменение.

Отредактировано 4kpt_III (Авг. 3, 2015 22:33:33)

Офлайн

#2 Авг. 4, 2015 06:56:12

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Массовый update

А какие данные у вас в файле? Точно их нельзя вычислить и базу одним запросом проапдейтить?



Офлайн

#3 Авг. 4, 2015 14:27:06

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Массовый update

neitro
    sql += str_update_ip_domain(arr[0], arr[1], arr[2]) 
    if i % 1000  == 0: 
	try:    # обработка исключения
	    cur.executescript(sql) # Выполняем SQL-запрос
	    sql = ''
	except sqlite.DatabaseError, err:
	    print u"Ошибка:", err
Ужас какой! Тут не весь код, но если я правильно понимаю, вы собираете в текстовой переменной текст 1000 sql-запросов и кормите этим базу? Собирайте данные в списке кортежей, а потом запускайте c executemany и биндингом параметров



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#4 Авг. 4, 2015 18:07:33

neitro
Зарегистрирован: 2015-03-13
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Массовый update

Rodegast
Индекс сделал?
Нет, на тот момент не делал - сейчас этим вопросом озадачился

4kpt_III
1. Не увидел здесь алхимию хотя смотрел в оба глаза.
2. Почему-бы перед тем, как обновить не проверить: а изменилось ли вообще поле?
3. Ну и индескы. Хотя об этом уже сказали. И не раз.
4. Sqlite хорош для малого хранения данных. Для чего-то сложнее нужно выбирать между PostgreSQL и Mongo (зависит от структуры данных). Учитывая Ваши данные предпочтительнее PostgreSQL.

она была до sqlite3
Т.е. вместо куска

	try:    # обработка исключения
	    cur.executescript(sql) # Выполняем SQL-запрос
	    sql = ''
	except sqlite.DatabaseError, err:
	    print u"Ошибка:", err

была строчка вида
	try:    # обработка исключения
	    session.query(Info).filter_by(name="%s" % value).update({'text1': text1})
	except:
	    print u"Ошибка:"

Особой разницы в скорости не заметил.

PooH
Ужас какой! Тут не весь код, но если я правильно понимаю, вы собираете в текстовой переменной текст 1000 sql-запросов и кормите этим базу? Собирайте данные в списке кортежей, а потом запускайте c executemany и биндингом параметров
Именно так я и делаю, как это не было прискорбно (про 1к UPDATE).
Второе предложение не понял - пошел гуглить инфу что это и с чем едят

FishHook
А какие данные у вас в файле? Точно их нельзя вычислить и базу одним запросом проапдейтить?

Ну у меня есть данные (грубо говоря):
name|text1|date1
их 10к штук

в базе инфа храниться в виде.
id|name|date1|date2|date3|text1|text2|text3|integer
по name нужно проапдейтить бд. Я не знаю как можно 1-м запросом это сделать. По крайней мере пока.

PS Для того что бы понять необходимость обновления нужно получить эти данные. И тут тоже стоит вопрос, как это сделать. Адскую конструкцию типа
Select (name,text1,date1) from table where name = ‘value1’ or name = ‘value2’ or … name = ‘value10000’
Но это кажется совсем не красивой конструкцией.

PPS Про индексы можете пока не говорить - вопрос изучаю)))) Как использую - расскажу о результатах

Офлайн

#5 Авг. 4, 2015 18:26:24

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Массовый update

neitro
Второе предложение не понял - пошел гуглить инфу что это и с чем едят
sql = '''UPDATE domains 
    SET text1 = ?, date1 = ?
    WHERE name = ?;
'''
дальше как раньше идете по файлу, но собираете свои данные в массив вида:
data = [('text1', date1, 'name'), ('text1', date1, 'name'), ('text1', date1, 'name'), ... ]
как набрали тысячу, или сколько желаете
cur.executemany(sql, data)
уйдут расходы времени на парсинг запросов, мне кажется они велики. Ну и транзакция будет фиксироваться один раз на тысячу вставок.

Ну и индекс конечно по name, вы же по нему все время ищите.



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#6 Авг. 4, 2015 18:38:25

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Массовый update

Вообще странная программа, которая сначала накапливает данные в текстовом файле, а потом этими данными апдейтит БД. Сразу нельзя что ли?



Офлайн

#7 Авг. 4, 2015 18:44:12

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Массовый update

neitro
Я не знаю как можно 1-м запросом это сделать.
Вопрос был конкретно такой
Точно их нельзя вычислить?
поясню, если например у меня есть таблица в БД
id|date|counter1|counter2|sum
и мне нужно во всех записях увеличить дату на 1 день и counter1 на единицу и посчитать сумму counter1 и counter2, то никакой файл тут городить не нужно и все изменения можно сделать одним запросом.



Офлайн

#8 Авг. 4, 2015 18:54:57

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Массовый update

Если вам не нужна собственно сама программа, а нужен результат (если это не учебный проект, а реальная производственная необходимость), то я бы попробовал так:
1. Загружаем данные из файла в БД. Насколько я понимаю, у вас CSV файл. SQLite умеет засасывать данные из CSV.
2. собственно апдейтим используя синтаксис

UPDATE table
SET columns = (SELECT .....)
WHERE ....



Офлайн

#9 Авг. 5, 2015 09:56:19

neitro
Зарегистрирован: 2015-03-13
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Массовый update

FishHook
Вообще странная программа, которая сначала накапливает данные в текстовом файле, а потом этими данными апдейтит БД. Сразу нельзя что ли?

Можно, даже нужно, но в данном конкретном случае - я изучал вопрос “какой кусок кода занимает много времени” и выяснил, что конкретно этот кусок, поэтому по нему и задал вопрос.

Офлайн

#10 Авг. 5, 2015 10:40:36

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Массовый update

neitro
она была до sqlite3

И куда алхимия писала? В Астрал? Если Вы другие БД еще не пробовали. Сложно поверить, что после алхимии Вы перешли на чистый SQL да еще и без алхимического core. Короче, алхимией тут и не пахло.

neitro
PS Для того что бы понять необходимость обновления нужно получить эти данные. И тут тоже стоит вопрос, как это сделать. Адскую конструкцию типа
Select (name,text1,date1) from table where name = ‘value1’ or name = ‘value2’ or … name = ‘value10000’
Но это кажется совсем не красивой конструкцией.

Получать порциями и обновлять, если нужно. Для этого есть in_ в алхимии.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version