Проблема в том, что вы выполняете тяжелую задачу в главном потоке, блокирующем цикл событий графического интерфейса, и это приводит к зависанию окна, и вы принудительно обновляете, используя QApplication::processEvents()
, вместо этого правильным решением является выполнить эту задачу тяжело в другом потоке.
import sys
from PyQt4 import QtCore, QtGui
import threading
class splashTest(QtGui.QDialog):
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(splashTest, self).__init__(parent)
self.setGeometry(000,000,800,400)
self.tabWidget = QtGui.QTabWidget(self)
self.tabWidget.setGeometry(QtCore.QRect(0, 0, 500, 500))
self.tabWidget.setObjectName("tabWidget")
self.tab1 = QtGui.QWidget()
self.tab2 = QtGui.QWidget()
self.tab3 = QtGui.QWidget()
self.tabWidget.addTab(self.tab1, "tab1")
self.tabWidget.addTab(self.tab2, "tab2")
self.tabWidget.addTab(self.tab3, "Click Me")
self.tabWidget.setCurrentIndex(1)
self.tabWidget.currentChanged.connect(self.whichTabIsSelected)
@QtCore.pyqtSlot(int)
def whichTabIsSelected(self, index):
if index == 2:
splash_pix = QtGui.QPixmap('splash.png')
splash = QtGui.QSplashScreen(self, splash_pix, QtCore.Qt.WindowStaysOnTopHint)
splash.setMask(splash_pix.mask())
splash.show()
for _ in range(2):
loop = QtCore.QEventLoop()
self.finished.connect(loop.quit)
threading.Thread(target=self.timeConsumingFunction).start()
loop.exec_()
splash.finish(self.tabWidget)
splash.close()
def timeConsumingFunction(self):
b = 0
for a in range(100000000):
b += a
print (b)
self.finished.emit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = splashTest()
myapp.show()
sys.exit(app.exec_())
LIKE
и =
- это разные операторы. Большинство ответов здесь сосредоточено на поддержке подстановочных знаков, и это не единственное различие между этими операторами!
=
- оператор сравнения, который работает с числами и строками. При сравнении строк оператор сравнения сравнивает целые строки .
LIKE
- строковый оператор, сравнивающий символ за символом .
Чтобы усложнить ситуацию, оба оператора используют сопоставление , которое может иметь важное влияние на результат сравнения.
Давайте сначала определим пример, в котором эти операторы дают явно разные результаты. Позвольте мне процитировать руководство MySQL:
В соответствии со стандартом SQL LIKE выполняет сопоставление для каждого символа, таким образом, он может выдавать результаты, отличные от оператора сравнения =:
mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
| 0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
| 1 |
+--------------------------------------+
Обратите внимание, что эта страница MySQL Руководство называется Функции сравнения строк , а =
не обсуждается, что означает, что =
не является строго функцией сравнения строк.
=
? Стандарт SQL § 8.2 описывает, как =
сравнивает строки:
Сравнение двух символьных строк определяется следующим образом:
a) Если длина в символах X не равна длине в символах Y, то более короткая строка фактически заменяется для целей сравнения , с копией самого , которая была расширена до длины более длинной строки путем конкатенации справа одного или нескольких символов , где выбирается символ заполнения на базе CS. Если CS имеет атрибут NO PAD, то символ заполнения является зависимым от реализации символом, отличным от любого символа в наборе символов X и Y, который сопоставляет меньше {{ 1}}, чем любая строка в CS. В противном случае символ заполнения - это .
b) Результат сравнения X и Y дается последовательностью сортировки CS.
c) В зависимости от последовательности сортировки две строки могут сравниваться как равные, даже если они имеют разную длину или содержат разные последовательности символов. Когда операции MAX, MIN, DISTINCT, ссылки на столбец группировки, а операторы UNION, EXCEPT и INTERSECT относятся к символьным строкам , конкретное значение, выбранное этими операции из набора таких равных значений зависят от реализации.
(Курсив добавлен)
Что это означает? Это означает, что при сравнении строк оператор =
является лишь тонкой оберткой вокруг текущего сопоставления. Сопоставление - это библиотека, в которой есть различные правила для сравнения строк. Вот пример двоичного сопоставления из MySQL :
static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
const uchar *s, size_t slen,
const uchar *t, size_t tlen,
my_bool t_is_prefix)
{
size_t len= MY_MIN(slen,tlen);
int cmp= memcmp(s,t,len);
return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}
Это конкретное сопоставление происходит для побайтного сравнения (поэтому оно называется «двоичным» - оно не придает особого значения строкам ). Другие сопоставления могут обеспечить более сложные сравнения.
Например, вот сортировка UTF-8 , которая поддерживает сравнения без учета регистра. Код слишком длинный для вставки сюда, но перейдите по этой ссылке и прочтите тело my_strnncollsp_utf8mb4 ()
. Это сопоставление может обрабатывать несколько байтов за раз и может применять различные преобразования (например, сравнение без учета регистра). Оператор =
полностью абстрагируется от капризов сопоставления.
LIKE
? Стандарт SQL § 8.5 описывает, как LIKE
сравнивает строки:
M LIKE P
истинно, если существует разделение M на подстроки так, что :
i)Подстрока M - это последовательность из 0 или более смежных <символьных представлений> s из M, и каждое <символьное представление> M является частью ровно одной подстроки.
ii) Если i-й спецификатор подстроки P является произвольным спецификатором символа , i-я подстрока M представляет собой любое одиночное <символьное представление>.
iii) Если i-ый спецификатор подстроки P является произвольным строковым спецификатором , то i-ая подстрока M является любой последовательностью 0 или более <символьное представление> s .
iv) Если i-й спецификатор подстроки P не является ни спецификатором произвольного символа, ни произвольным спецификатором строки, , то i-я подстрока M равна этой подстроке { Спецификатор {1}} в соответствии с последовательностью сортировки
, без добавления символов к M, и имеет ту же длину, что и эта подстрока {{1} } спецификатор. v) Количество подстрок в M равно количеству спецификаторов подстроки в P.
(выделение добавлено).
Это довольно многословно, поэтому давайте разберемся с ним. Пункты ii и iii относятся к подстановочным знакам _
и %
соответственно. Если P
не содержит подстановочных знаков, применяется только пункт iv. Это тот случай, который представляет интерес со стороны ОП.
В этом случае он сравнивает каждую «подстроку» (отдельные символы) в M
с каждой подстрокой в P
, используя текущее сопоставление.
Суть в том, что при сравнении строк =
сравнивается вся строка, а LIKE
сравнивает по одному символу за раз.Оба сравнения используют текущее сопоставление. Это различие в некоторых случаях приводит к разным результатам, о чем свидетельствует первый пример в этом посте.
Какой из них использовать? Никто не может вам этого сказать - вам нужно использовать тот, который подходит для вашего варианта использования. Не выполняйте оптимизацию преждевременно, переключая операторы сравнения.
=
и LIKE
не то же;
=
соответствия точная строка LIKE
соответствия строка, которая может содержать подстановочные знаки (%) Действительно это сводится к тому, что Вы хотите, чтобы запрос сделал. Если Вы подразумеваете, что точное совпадение затем использует =. Если Вы имеете в виду более нечеткое соответствие, то используйте КАК. Высказывание, что Вы имеете в виду, обычно является хорошей политикой с кодом.
ПОДОБНОЕ ключевое слово, несомненно, идет с "ценником производительности", присоединенным. Тем не менее, если у Вас будет поле ввода, которое могло бы потенциально включать подстановочные символы, которые будут использоваться в Вашем запросе, то я рекомендую использовать КАК , только если вход содержит один из подстановочных знаков. Иначе используйте стандарт, равный сравнению.
С наилучшими пожеланиями...
Используя = избегает подстановочных знаков и конфликтов специальных символов в строке, когда Вы создаете запрос во время выполнения.
Это делает жизнь программиста легче, не имея необходимость выйти из всех специальных подстановочных символов, которые могли бы закрадываться в оператор LIKE и не приведение к намеченному результату. В конце концов, = 99%-й сценарий варианта использования, это была бы боль для выхода из них каждый раз.
закатывает глаза в 90-х
, я также подозреваю, что это немного медленнее, но я сомневаюсь, что значительно, при отсутствии подстановочных знаков в шаблоне.
Зависит от системы баз данных.
Обычно без специальных символов, да, = и КАК то же.
Некоторые системы баз данных, однако, могут рассматривать настройки сопоставления по-другому с различными операторами.
, Например, в сравнениях MySQL с = на строках всегда нечувствительно к регистру по умолчанию, таким образом, КАК без специальных символов то же. На некотором другом RDBMS ЛЮБЯТ, нечувствительно к регистру, в то время как = не.
Одно различие - кроме возможности использовать подстановочные знаки с ПОДОБНЫМ - находится в конечных пробелах: = оператор игнорирует конечный пробел, но КАК не делает.
LIKE
и =
отличаются. LIKE
то, что Вы использовали бы в поисковом запросе. Это также позволяет подстановочные знаки как _
(простой символьный подстановочный знак) и %
(мультисимвольный подстановочный знак).
=
должен использоваться, если Вы хотите точные совпадения, и это будет быстрее.
Равняние (оператор =) является "оператором сравнения, сравнивает два значения для равенства". Другими словами, в SQL-операторе, это не возвратит true, если обе стороны уравнения не будут равны. Например:
SELECT * FROM Store WHERE Quantity = 200;
оператор LIKE "реализует сравнение соответствия шаблона", которое пытается соответствовать "строковому значению против строки образца, содержащей подстановочные символы". Например:
SELECT * FROM Employees WHERE Name LIKE 'Chris%';
КАК обычно используется только со строками и равняется (я верю), быстрее. Равняется подстановочным символам обработок оператора как буквенным символам. Различие в возвращенных результатах следующие:
SELECT * FROM Employees WHERE Name = 'Chris';
И
SELECT * FROM Employees WHERE Name LIKE 'Chris';
возвратил бы тот же результат, хотя использование КАК будет обычно занимать больше времени, поскольку это - соответствие шаблона. Однако
SELECT * FROM Employees WHERE Name = 'Chris%';
И
SELECT * FROM Employees WHERE Name LIKE 'Chris%';
возвратил бы различные результаты, куда использование "=" результаты только в результатах с "% Chris", возвращаемым и т.п. оператор, возвратит что-либо запускающееся с "Chris".
Hope, которая помогает. Некоторая хорошая информация может быть найдена здесь .
При поиске точного совпадения можно использовать обоих, = и КАК.
Используя "=" крошечный бит быстрее в этом случае (поиск точного совпадения) - можно проверить это сами при наличии того же запроса дважды в Studio управления SQL Server, однажды использующий "=", после того как использующий "КАК" и затем использующий "Запрос" / "Включают фактический план выполнения".
Выполняют два запроса, и необходимо видеть результаты дважды плюс два фактических плана выполнения. В моем случае они были разделены 50% по сравнению с 50%, но "=" план выполнения имеет меньшую "предполагаемую стоимость поддерева" (отображенный, когда Вы нависаете над крайним левым полем "SELECT") - но снова, это - действительно не огромная разница.
, Но когда Вы начнете искать с подстановочными знаками в Вашем КАК выражение, поисковая производительность будет неясный. Поиск "КАК % Фрезы" может все еще быть довольно быстрым - SQL Server может использовать индекс на том столбце, если существует тот. Поиск "КАК %expression %" является ужасно медленным, так как единственный способ, которым SQL Server может удовлетворить этот поиск, путем выполнения полного сканирования таблицы. Так будьте осторожны со своим LIKE's!
Marc
Чтобы ответить на исходный вопрос, касающийся производительности, он сводится к использованию индекса . Когда происходит простое сканирование таблицы, «LIKE» и «=» идентичны . Когда используются индексы, это зависит от того, как сформировано предложение LIKE. Более конкретно, каково расположение подстановочных знаков?
Примите во внимание следующее:
CREATE TABLE test(
txt_col varchar(10) NOT NULL
)
go
insert test (txt_col)
select CONVERT(varchar(10), row_number() over (order by (select 1))) r
from master..spt_values a, master..spt_values b
go
CREATE INDEX IX_test_data
ON test (txt_col);
go
--Turn on Show Execution Plan
set statistics io on
--A LIKE Clause with a wildcard at the beginning
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '%10000'
--Results in
--Table 'test'. Scan count 3, logical reads 15404, physical reads 2, read-ahead reads 15416, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index SCAN is 85% of Query Cost
--A LIKE Clause with a wildcard in the middle
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '1%99'
--Results in
--Table 'test'. Scan count 1, logical reads 3023, physical reads 3, read-ahead reads 3018, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost for test data, but it may result in a Table Scan depending on table size/structure
--A LIKE Clause with no wildcards
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO
--an "=" clause = does Index Seek same as above
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col = '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO
DROP TABLE test
Также может быть незначительная разница в создании плана запроса при использовании "=" и "LIKE".