具有多个表和大数据的查询优化

时间:2017-06-28 20:17:07

标签: mysql

我正在为我的硕士学位做一个项目,我有一个500GB的MySQL数据库。我的项目与StackOverflow有关,因此它为何如此之大。我需要优化一个选择查询,因为运行它需要一分钟,而且我认为它太慢了,特别是我使用Java制作GUI并且只是等待一分钟并不是一个好主意。这是我的表格和相关信息:

表:包含22 222 747条记录的标签。

Tags Table

标签索引。

Tags Index

表:与8 117 955条记录的链接。盖子和辅助指数。

Links Table

链接索引

Links Index

表:14 401 786条记录的答案。关于援助和qid的指数。

Answers Table

答案索引

Answers Index

表:7 495 155条记录的问题。

Questions Table

问题索引。

Questions Index

我的想法是收集人们在答案中发布的重定向链接,我的工具会根据用户的需求推荐一些链接。用户可以指定许多标签,但为了简单起见,我们假设有2个标签。这是我正在使用的查询:

from tkinter import*
import tkinter.messagebox

newInstList=[]

def addItem(event=None):
    global back_add,quantityentry,itemEntry,itemEntry1,quantityentry1
    itemFrameTop=Frame(root, width=800,height=100,bg='pink')
    itemFrameTop.grid_propagate(False)
    itemFrameTop.grid(row=0)
    area1_item = Label(itemFrameTop, text='CSSD', pady=5,padx=230)
    area1_item.config(font=("Courier", 30))
    area1_item.grid_propagate(False)
    area1_item.grid(row=0,column=1,sticky=NE)
    clinic_1 = Label(itemFrameTop, text='Clinic 1', bg='red', fg='white', bd=5)
    clinic_1.config(font=("Courier", 15))
    clinic_1.grid_propagate(False)
    clinic_1.grid(row=1, sticky=W,padx=10)
    itemFrameMid=Frame(root,width=700,height=600,bg='blue')
    itemFrameMid.grid_propagate(False)
    itemFrameMid.grid(row=1)
    itemname=Label(itemFrameMid,text='Item name:')
    itemname.config(font=('Arial,15'))
    itemname.grid_propagate(False)
    itemname.grid(row=1,sticky=E)
    quantity=Label(itemFrameMid,text='Qty:')
    quantity.config(font=('Arial,15'))
    quantity.grid_propagate(False)
    quantity.grid(row=1,column=3, sticky=E,padx=10)
    itemEntry=Entry(itemFrameMid)
    itemEntry.config(font=('Arial,15'))
    itemEntry.grid(row=1,column=1,sticky=EW,padx=30,pady=10)
    itemEntry1 = Entry(itemFrameMid)
    itemEntry1.config(font=('Arial,15'))
    itemEntry1.grid(row=2, column=1)

    quantityentry=Entry(itemFrameMid,width=5)
    quantityentry.config(font=('Arial',15))
    quantityentry.grid(row=1, column=4)
    quantityentry1 = Entry(itemFrameMid, width=5)
    quantityentry1.config(font=('Arial', 15))
    quantityentry1.grid(row=2, column=4,padx=10)

"""When I click save button another small window appears"""
    okbutton = Button(itemFrameMid, text='Save', command=saveCheck)
    okbutton.config(font=('Arial', 12))
    okbutton.grid(row=3, column=4, padx=15)

    back_add = Label(itemFrameTop, text='Back')
    back_add.config(font=('Courier,15'))
    back_add.grid(row=0, sticky=W, padx=30)
    back_add.bind('<Button-1>', main_page)
    back_add.bind('<Enter>', red_text_back1)
    back_add.bind('<Leave>', black_text_back1)

def saveCheck():
    saveQuestion=tkinter.messagebox.askquestion('CSSD', 'Are you sure you want to save?')
    if saveQuestion == 'yes':
        newInstList.append(itemEntry.get())
        newInstList.append(quantityentry.get())
        newInstList.append(itemEntry1.get())
        newInstList.append(quantityentry1.get())
        print(newInstList)
        main_page()
    elif saveQuestion == 'no':
        pass

def red_text_back1(event=None):
    back_add.config(fg='red')

def black_text_back1(event=None):
    back_add.config(fg='black')

def red_text_add(event=None):
    addnew.config(fg='red')

def black_text_add(event=None):
    addnew.config(fg='black')

def main_page(event=None):

    global addnew,usedInst,logOut
    frame1 = Frame(root, width=800, height=100,bg='pink')
    frame1.grid(row=0, column=0, sticky="nsew")
    frame1.grid_propagate(False)
    midframe1=Frame(root,width=800,height=600)
    midframe1.grid_propagate(False)
    midframe1.grid(row=1)

    area1 = Label(frame1, text='CSSD',pady=5,padx=350)
    area1.config(font=("Courier", 30))
    area1.grid(row=0)
    clinic1=Label(frame1,text='Clinic 1',bg='red',fg='white',bd=5)
    clinic1.config(font=("Courier", 15))
    clinic1.grid_propagate(False)
    clinic1.grid(row=1,sticky=W,padx=10)
    addnew=Label(midframe1,text='+ Add new item')
    addnew.config(font=('Arial',15))
    addnew.grid(row=2,column=1,sticky=E,ipadx=50)
    addnew.bind('<Button-1>', addItem)
    addnew.bind('<Enter>', red_text_add)
    addnew.bind('<Leave>', black_text_add)

root = Tk()
root.geometry('800x600')

这是上述查询的解释图片:

Explain

如果用户要求3个或更多标签,那么我会再添加1个OR条件并计算(*)=标签数量。

我不是MySQL的专家,所以我相信可以有办法改进它。我为qid,aid和tag创建了长度为10的索引。如果可能的话,我宁愿避免更改表,除非没有办法避免它。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

此时您的查询必须处理&gt; 1.6毫升行。使用标签表上的多列索引可能会减少这种情况:

CREATE INDEX tags2 ON tags (tags, qid);

或替代方案(取决于数据哪种方式最佳,我无法在没有真实数据库的情况下测试):

CREATE INDEX tags3 ON tags (qid, tag);

许多索引的缺点是插入和更新变慢。为防止这种情况发生,请删除根据计划未使用的索引。

其他可能有用的索引是:

CREATE INDEX ans1 ON answers(qid,aid);

或者

CREATE INDEX ans2 ON answers(aid,qid);