У меня есть таблица с ~ 133M строк и 16 столбцов.Я хочу создать 14 таблиц в другой базе данных на том же сервере для каждого из столбцов 3-16 (столбцы 1 и 2 - `id`
и `timestamp`
, которые также будут в последних 14 таблицах, но не будут иметь своих собственныхтаблица), где каждая таблица будет иметь имя исходного столбца.Возможно ли это сделать исключительно с помощью сценария SQL?Мне кажется логичным, что это было бы предпочтительным и самым быстрым способом сделать это.
В настоящее время у меня есть скрипт Python, который «работает», анализируя дамп CSV исходной таблицы (тестирование с 50 строками), создание новых таблиц и добавление связанных значений, но это очень медленно (я оценил почти 1 год для переноса всех 133M строк, что явно неприемлемо).Я впервые использую SQL в любом качестве, и я уверен, что мой код может быть ускорен, но я не уверен, как из-за моего незнакомого с SQL.Большая строковая команда SQL в середине была скопирована из некоторого другого кода в нашей кодовой базе.Я пытался использовать транзакции, как показано ниже, но это не оказало существенного влияния на скорость.
import re
import mysql.connector
import time
# option flags
debug = False # prints out information during runtime
timing = True # times the execution time of the program
# save start time for timing. won't be used later if timing is false
start_time = time.time()
# open file for reading
path = 'test_vaisala_sql.csv'
file = open(path, 'r')
# read in column values
column_str = file.readline().strip()
columns = re.split(',vaisala_|,', column_str) # parse columns with regex to remove commas and vasiala_
if debug:
print(columns)
# open connection to MySQL server
cnx = mysql.connector.connect(user='root', password='<redacted>',
host='127.0.0.1',
database='measurements')
cursor = cnx.cursor()
# create the table in the MySQL database if it doesn't already exist
for i in range(2, len(columns)):
table_name = 'vaisala2_' + columns[i]
sql_command = "CREATE TABLE IF NOT EXISTS " + \
table_name + "(`id` BIGINT(20) NOT NULL AUTO_INCREMENT, " \
"`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, " \
"`milliseconds` BIGINT(20) NOT NULL DEFAULT '0', " \
"`value` varchar(255) DEFAULT NULL, " \
"PRIMARY KEY (`id`), " \
"UNIQUE KEY `milliseconds` (`milliseconds`)" \
"COMMENT 'Eliminates duplicate millisecond values', " \
"KEY `timestamp` (`timestamp`)) " \
"ENGINE=InnoDB DEFAULT CHARSET=utf8;"
if debug:
print("Creating table", table_name, "in database")
cursor.execute(sql_command)
# read in rest of lines in CSV file
for line in file.readlines():
cursor.execute("START TRANSACTION;")
line = line.strip()
values = re.split(',"|",|,', line) # regex split along commas, or commas and quotes
if debug:
print(values)
# iterate of each data column. Starts at 2 to eliminate `id` and `timestamp`
for i in range(2, len(columns)):
table_name = "vaisala2_" + columns[i]
timestamp = values[1]
# translate timestamp back to epoch time
try:
pattern = '%Y-%m-%d %H:%M:%S'
epoch = int(time.mktime(time.strptime(timestamp, pattern)))
milliseconds = epoch * 1000 # convert seconds to ms
except ValueError: # errors default to 0
milliseconds = 0
value = values[i]
# generate SQL command to insert data into destination table
sql_command = "INSERT IGNORE INTO {} VALUES (NULL,'{}',{},'{}');".format(table_name, timestamp,
milliseconds, value)
if debug:
print(sql_command)
cursor.execute(sql_command)
cnx.commit() # commits changes in destination MySQL server
# print total execution time
if timing:
print("Completed in %s seconds" % (time.time() - start_time))
Это не должно быть невероятно оптимизировано;Это вполне приемлемо, если машина должна работать в течение нескольких дней, чтобы сделать это.Но 1 год это слишком долго.