【问题标题】:Python threading and SQLPython 线程和 SQL
【发布时间】:2015-11-02 02:14:23
【问题描述】:

我的问题基本上是数据库交互是否有最佳实践方法,我是否在下面做一些愚蠢/错误的事情,这会浪费处理时间。

我的程序从网站提取数据并写入 SQL 数据库。速度非常重要,我希望能够尽快刷新数据。我已经尝试了很多方法,但我觉得它仍然太慢了——也就是说,用更好的方法/设计来与数据库交互可能会更好,我确信我会犯各种各样的错误。我可以非常快速地将数据下载到内存中,但写入数据库需要更长的时间。

我尝试过的 3 种主要方法是:

  • 提取数据并填充 SQL 命令列表的线程,当 线程完成在主线程中运行sql
  • 提取数据并推送到 SQL 的线程(按照以下代码)
  • 提取数据并使用单独线程填充 q 的线程 轮询 q 并推送到数据库。

代码如下:

import MySQLdb as mydb

class DatabaseUtility():
    def __init__(self):
        """set db parameters"""

    def updateCommand(self, cmd):
        """run SQL commands and return number of matched rows"""
        try:
            self.cur.execute(cmd)
            return int(re.search('Rows matched: (\d+)', self.cur._info).group(1))
        except Exception, e:
            print ('runCmd error: ' + str(e))
            print ('With SQL: ' + cmd)
            return 0

    def addCommand(self, cmd):
        """write SQL command to db"""
        try:
            self.cur.execute(cmd)
            return self.cur.rowcount
        except Exception, e:
            print ('runCmd error: ' + str(e))
            print ('With SQL: ' + cmd)
            return 0

我创建了一个实例化数据库连接的类,如下所示:

from Queue import Queue
from threading import Thread
import urllib2
import json
from databasemanager import DatabaseUtility as dbU
from datalinks import getDataLink, allDataLinks

numThreads = 3
q = Queue()
dbu = dbU()

class OddScrape():
    def __init__(self, name, q):
        self.name = name
        self.getOddsData(self.name, q)

    def getOddsData(self, i, q):
        """Worker thread - parse each datalink and update / insert to db"""
        while True:
            #get datalink, create db connection
            self.dbu = dbU()
            matchData = q.get()   

            #load data link using urllib2 and do a bunch of stuff 
            #to parse the data to the required format

            #try to update in db and insert if not found
            sql = "sql to update %s" %(params)
            update = self.dbu.updateCommand(sql)
            if update < 1:
                sql = "sql to insert" %(params)
                self.dbu.addCommand(sql)  
        q.task_done()
        self.dbu.dbConClose()
        print eventlink

def threadQ():
    #set up some threads
    for i in range(numThreads):
        worker = Thread(target=OddScrape, args=(i, q,))
        worker.start()
    #get urldata for all matches required and add to q
    matchids = dbu.runCommand("sql code to determine scope of urls")
    for match in matchids:
        sql = "sql code to get url data %s" %match
        q.put(dbu.runCommand(sql))
    q.join()

我还在我正在编写的表格中添加了一个索引,这似乎有点帮助但并不明显:

CREATE INDEX `idx_oddsdata_bookid_datalinkid` 
ON `dbname`.`oddsdata` (bookid, datalinkid) COMMENT '' ALGORITHM DEFAULT LOCK DEFAULT;

【问题讨论】:

    标签: python mysql multithreading optimization


    【解决方案1】:

    多线程意味着多个连接。尽管在 MySQL 中获得连接是“快速的”,但它不是即时的。我不知道获得连接与运行查询的相对速度,但我怀疑你的多线程想法是否会获胜。

    您能否向我们展示您需要运行的实际查询(SQL,而不是 Python 代码)的示例。我们可能有关于组合查询、改进索引等方面的建议。也请提供SHOW CREATE TABLE。 (你提到了CREATE INDEX,但断章取义是没用的。)

    您似乎正在执行一个多步骤过程,该过程可以折叠成INSERT ... ON DUPLICATE KEY UPDATE ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多