QSqlDatabase замедляется
23.03.2016, 12:45. Показов 649. Ответов 2
Написал маленькую базу данных из 3-х таблиц. В базе хранится список категорий, элементов и информации этих элементов.
На выходе получается дерево из 8 подкатегорий.
Так вот, при первом запросе чтение 11кб базы проходит за чуть меньше секунды.
дальше этот показатель растёт в два раза при каждом повторном чтении.
таким образом после 10 повторных чтений базы, она будет читаться уже секунд 11.
пробовал отключать всё взаимодествие с интерфейсом, думая что проблема в нём, но база читается также медленно.
Пробовал вставлять везде транзакции и коммиты, стало примерно на 1/4 быстрее, но всё равно при повторных запросах скорость чтения падает.
при этом нагрузка на процессор каждый раз прежняя, 100% одного ядра все 11 секунд.
кто-нибудь может подсказать, куда нужно копать?
base.h
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| class SQLbase : public QObject
{
Q_OBJECT
public:
explicit SQLbase(QObject *parent = 0); //конструктор
~SQLbase(); //деструктор
private:
//SQL
QSqlDatabase sql_sector;
//Query
QSqlQuery query_sector;
void crTable(QSqlDatabase&base,QString str,QString err); //создать таблицу в базе
//статические экземпляры
Sector sector;
SectorFolder sectorfolder;
signals:
public:
void OpenSector(QString filename); //открыть список секторов
void CreateSector(QString filename); //создать список секторов
void CloseSector(); //закрыть список секторов
/*---------------------------------------------------------
* публичные функции для работы с базой
---------------------------------------------------------*/
//Info
int Sector_VersionGet(); //получить версию списка секторов
void Sector_VersionSet(int ver); //установить версию списка секторов
/*---------------------------------------------------------
* SECTOR
---------------------------------------------------------*/
//Folder
int Sector_FolderAdd(int ParentID,QString Name,SectorFolderType Type,double Factor,int PhotoID);
SectorFolder& Sector_FolderGet(int ID);
SectorFolder& Sector_FolderGetAt(int index);
void Sector_FolderRemove(int ID);
bool Sector_FolderExists(int ID);
void Sector_FolderClear();
int Sector_FolderFreeID();
int Sector_FolderCount();
//Sector
int Sector_SectorAdd(int FolderID, QString Name);
Sector& Sector_SectorGet(int ID);
Sector& Sector_SectorGetAt(int index);
void Sector_SectorRemove(int ID);
bool Sector_SectorExists(int ID);
void Sector_SectorClear();
int Sector_SectorFreeID();
int Sector_SectorCount();
//SectorItems
int Sector_ItemAdd(int SectorID,QString Street,QString Number,
bool Elite = false,int House = 0,int Apartments =0,
int Indoors = 0,QString Comment = "",bool Confirmed = false);
QList<SectorItem>Sector_ItemGet(int ID);
void Sector_ItemRemove(int ID);
bool Sector_ItemExists(int ID);
void Sector_ItemClear();
int Sector_ItemFreeID();
int Sector_ItemCount();
}; |
|
открытие базы:
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
| void SQLbase::OpenSector(QString filename)
{
if(FileExists(filename))
{
log("SQLbase::OpenSector");
sql_sector.setDatabaseName(filename);
if(!sql_sector.open())
{
logarg("!sql.open(): %1")
.arg(sql_sector.lastError().text())
.logerror();
return;
}
QSqlQuery qr(sql_sector);
this->query_sector = qr;
/*if(Sector_VersionGet()<0)
{
sql.close();
CreateSector(filename);
}*/
}else CreateSector(filename);
}
/*---------------------------------------------------------*/
void SQLbase::CreateSector(QString filename)
{
FileDelete(filename);
if(!FileExists(filename))
{
log("SQLbase::CreateSector");
sql_sector.setDatabaseName(filename);
if(!sql_sector.open())
{
logarg("!sql.open(): %1")
.arg(sql_sector.lastError().text())
.logerror();
return;
}
QSqlQuery qr(sql_sector);
this->query_sector = qr;
crTable(sql_sector,bdefBaseCreateInfo, "!crTable SQLbase::CreateSector bdefBaseCreateInfo");
crTable(sql_sector,bdefSectorCreateFolders, "!crTable SQLbase::CreateSector bdefSectorCreateFolders");
crTable(sql_sector,bdefSectorCreateSectors, "!crTable SQLbase::CreateSector bdefSectorCreateSectors");
crTable(sql_sector,bdefSectorCreateSectorItems, "!crTable SQLbase::CreateSector bdefSectorCreateSectorItems");
//query_sector.exec( QString(bdefSectorInsertInfo).arg(VerSector) );
Sector_VersionSet(VerSector);
}
}
/*---------------------------------------------------------*/
void SQLbase::CloseSector()
{
log("SQLbase::CloseSector");
sql_sector.close();
} |
|
реализация чтения
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
| /*---------------------------------------------------------
* FOLDER
---------------------------------------------------------*/
int SQLbase::Sector_FolderAdd(int ParentID, QString Name, SectorFolderType Type, double Factor, int PhotoID)
{
logarg("SQLbase::Sector_FolderAdd(%1,'%2',%3,%4,%5)")
.arg(ParentID)
.arg(Name)
.arg(Type)
.arg(Factor)
.arg(PhotoID)
.log();
;
int newID = Sector_FolderFreeID();
if(newID<0)
return -1;
if(!query_sector().exec(
QString(bdefSectorInsertFolders)
.arg(newID)
.arg(Name)
.arg(Type)
.arg(Factor)
.arg(PhotoID)
.arg(ParentID)
)
)
{
logarg("SQLbase::Sector_FolderAdd bdefSectorInsertFolders: %1")
.arg(query_sector().lastError().text())
.logerror();
return -1;
}
return newID;
}
/*---------------------------------------------------------*/
SectorFolder &SQLbase::Sector_FolderGet(int ID)
{
log("Sector_FolderGet(%d)",ID);
sectorfolder.clear();
if(!query_sector().exec(QString(bdefSectorSelectFolders).arg(ID)))
{
logarg("SQLbase::Sector_FolderGet: %1")
.arg(query_sector().lastError().text())
.logerror();
return sectorfolder;
}
while(query_sector().next())
{
QSqlRecord rec = query_sector().record();
QVariant var[] = {
query_sector().value(rec.indexOf("ID")),
query_sector().value(rec.indexOf("Name")),
query_sector().value(rec.indexOf("Type")),
query_sector().value(rec.indexOf("Factor")),
query_sector().value(rec.indexOf("PhotoID")),
query_sector().value(rec.indexOf("Parent")),
};
sectorfolder
.setID(var[0].toInt())
.setName(var[1].toString())
.setType((SectorFolderType)var[2].toInt())
.setFactor(var[3].toString().toDouble())
.setPhotoID(var[4].toInt())
.setParent(var[5].toInt())
;
return sectorfolder;
}
logerror("SQLbase::Sector_FolderGet no Folder found");
return sectorfolder;
}
SectorFolder&SQLbase::Sector_FolderGetAt(int index)
{
log("Sector_FolderGetAt(%d)",index);
sectorfolder.clear();
if(!query_sector().exec(bdefSectorSelectFoldersAll))
{
logarg("SQLbase::Sector_FolderGetAt: %1")
.arg(query_sector().lastError().text())
.logerror();
return sectorfolder;
}
int i = 0;
while(query_sector().next())
{
if(i++<index)
continue;
QSqlRecord rec = query_sector().record();
QVariant var = query_sector().value(rec.indexOf("ID"));
return Sector_FolderGet(var.toInt());
}
logerror("SQLbase::Sector_FolderGetAt no Folder found");
return sectorfolder;
}
/*---------------------------------------------------------*/
void SQLbase::Sector_FolderRemove(int ID)
{
log("SQLbase::Sector_FolderRemove(%d)",ID);
if(!query_sector().exec(
QString(bdefSectorRemoveFolders)
.arg(ID)
)
)
{
logarg("SQLbase::Sector_FolderRemove bdefSectorRemoveFolders: %1")
.arg(query_sector().lastError().text())
.logerror();
return;
}
}
/*---------------------------------------------------------*/
bool SQLbase::Sector_FolderExists(int ID)
{
log("SQLbase::Sector_FolderExists(%d)",ID);
if(!query_sector().exec(QString(bdefSectorSelectFolders).arg(ID)))
{
logarg("SQLbase::Sector_FolderGet: %1")
.arg(query_sector().lastError().text())
.logerror();
return false;
}
return query_sector().next();
}
/*---------------------------------------------------------*/
void SQLbase::Sector_FolderClear()
{
log("SQLbase::Sector_FolderClear(%1)");
if (!query_sector().exec(bdefSectorDeleteFolders))
logarg("SQLbase::Sector_FolderClear bdefSectorDeleteFolders: %1")
.arg(query_sector().lastError().text())
.logerror();
}
/*---------------------------------------------------------*/
int SQLbase::Sector_FolderFreeID()
{
log("Sector_FolderFreeID");
int freeID = 1;
QList<int> list;
if(!query_sector().exec(bdefSectorSelectFoldersAll))
{
logarg("SQLbase::Sector_FolderFreeID: %1")
.arg(query_sector().lastError().text())
.logerror();
return -1;
}
while(query_sector().next())
{
QSqlRecord rec = query_sector().record();
QVariant var = query_sector().value(rec.indexOf("ID"));
list.append(var.toInt());
}
for(int i=0;i<list.count();i++)
{
if(list[0]==freeID)
{
freeID++;
i=0;
}
}
return freeID;
}
/*---------------------------------------------------------*/
int SQLbase::Sector_FolderCount()
{
log("Sector_FolderCount");
if(!query_sector().exec(bdefSectorSelectFoldersAll))
{
logarg("SQLbase::Sector_FolderCount: %1")
.arg(query_sector().lastError().text())
.logerror();
return -1;
}
int count = 0;
while(query_sector().next())
count++;
return count;
} |
|
константы запросов для QString
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| /*---------------------------------------------------------
*
* SECTOR
*
---------------------------------------------------------*/
#ifdef BASESECTOR
//CREATE
#define bdefSectorCreateFolders \
"CREATE TABLE Folders ("\
" ID INT PRIMARY KEY,"\
" Name TEXT,"\
" Type INT,"\
" Factor TEXT,"\
" PhotoID INT,"\
" Parent INT"\
");"
/*---------------------------------------------------------*/
//INSERT
#define bdefSectorInsertFolders \
"INSERT OR REPLACE INTO Folders(ID, Name, Type, Factor, PhotoID, Parent) "\
"VALUES (%1, '%2', %3, '%4', %5, %6);"
/*---------------------------------------------------------*/
//SELECT
#define bdefSectorSelectFolders \
"SELECT * FROM Folders WHERE ID = %1;"
/*---------------------------------------------------------*/
//SELECT ALL
#define bdefSectorSelectFoldersAll \
"SELECT * FROM Folders;"
/*---------------------------------------------------------*/
//REMOVE
#define bdefSectorRemoveFolders \
"DELETE FROM Folders WHERE ID = %1;"
/*---------------------------------------------------------*/
//CLEAR
#define bdefSectorDeleteFolders \
"DELETE FROM Folders;"
/*---------------------------------------------------------*/
#endif //BASESECTOR |
|
Добавлено через 14 минут
функция чтения базы:
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
| //добавить элементы в дерево
int count = base->Sector_FolderCount();
int bssf = BSSF_REGULAR;
int a = 0,b = 0,c = 0;
log("BSSF_REGULAR");
while(bssf<BSSF_DONE)
{
SectorFolder sf;
Sector s;
QList<SectorItem>si;
switch(bssf)
{
case BSSF_REGULAR:
{
if(a<count)
{
sf = base->Sector_FolderGetAt(a);
a++;
}else{
bssf++;
log("BSSF_LOSTED");
count = lostItems.count();
continue;
}
}break;
case BSSF_LOSTED:
{
if(b<count)
{
sf = base->Sector_FolderGet(lostItems[b]);
b++;
}else{
bssf++;
count = base->Sector_SectorCount();
log("BSSF_SECTOR");
continue;
}
}break;
case BSSF_SECTOR:
{
if(c<count)
{
s = base->Sector_SectorGetAt(c);
si = base->Sector_ItemGet(s.getID());
c++;
}else{
bssf++;
log("BSSF_DONE");
continue;
}
}break;
default:
{
logerror("MainWindow::baseShowSector bssf>=BSSF_DONE: %d",bssf);
return;
}
}
if(bssf==BSSF_REGULAR||bssf==BSSF_LOSTED)
{
if(sf.getID()==-1)
{
logerror("whaaaat? [%d,%d,%d,%d]",a,b,c,bssf);
continue;
}
//заголовок элемента
QStringList sl;
sl << sf.getName();
sl << QString("ID:%1;Type:%2;Factor:%3;PhotoID:%4;Parent:%5")
.arg(sf.getID())
.arg(sf.getType())
.arg(sf.getFactor())
.arg(sf.getPhotoID())
.arg(sf.getParent());
if(sf.getParent()==0)
{
//корень
QTreeWidgetItem*item = new QTreeWidgetItem(sl);
item->setIcon(0,QIcon(getSectorIcon((gsi)sf.getType())));
tree->addTopLevelItem( item );
list << *new sfitem(sf.getID(),item);
}else{
//дочерний
bool alpha = false;
for(int j=0;j<list.count();j++)
{
if(list[j].ID!=sf.getParent())
continue;
//родительский найден
alpha = true;
QTreeWidgetItem*item = new QTreeWidgetItem(list[j].qtwi,sl);
item->setIcon(0,QIcon(getSectorIcon((gsi)sf.getType())));
list << *new sfitem(sf.getID(),item);
break;
}
//если не найден, добавить в потерянные
if(!alpha)
lostItems.append(sf.getID());
}
//END OF if(bssf==BSSF_REGULAR||bssf==BSSF_LOSTED)
}else
if(bssf==BSSF_SECTOR)
{
if(s.getID()==-1)
{
logerror("whaaaat? [%d,%d,%d,%d]",a,b,c,bssf);
continue;
}
//заголовок элемента
QStringList sl;
sl << s.getName();
sl << QString("ID:%1;House:%2;Capacity:%3;LocID:%4;Parent:%5")
.arg(s.getID())
.arg(s.getHouse())
.arg(s.getCapacity())
.arg(s.getLocID())
.arg(s.getParent());
for(int i=0;i<list.count();i++)
{
if(list[i].ID!=s.getParent())
continue;
QTreeWidgetItem*item = new QTreeWidgetItem(list[i].qtwi,sl);
item->setIcon(0,QIcon(getSectorIcon(GSI_SECTOR)));
//listsector << *new sfitem(s.getID(),item);
for(int j=0;j<si.count();j++)
{
if(si[j].getID()==-1)
{
logerror("whaaaat? [%d,%d,%d,%d]",a,b,c,bssf);
continue;
}
//заголовок элемента
QStringList sl;
sl << "[#]";
sl << QString("Street:'%1';Number:'%2';Elite:%3;House:%4;Apartments:%5;Indoors:%6;Comment:'%7';Confirmed:%8;")
.arg(si[j].getStreet())
.arg(si[j].getNumber())
.arg(si[j].getElite())
.arg(si[j].getHouse())
.arg(si[j].getApartments())
.arg(si[j].getIndoors())
.arg(si[j].getComment())
.arg(si[j].getConfirmed());
QTreeWidgetItem*sitem = new QTreeWidgetItem(item,sl);
}
}
} |
|
0
|