Выбор Postgresql * от производительности таблицы по сравнению с MySql

У меня есть база данных MySQL, которую я портирую на PostgreSQL (из-за функций GIS).

Многие таблицы имеют сотни тысяч строк, таким образом, я должен иметь в виду производительность.

Моя проблема состоит в том, что PostgreSQL кажется плачевно медленным...

Например, если я делаю простой ВЫБОР * ОТ [таблицы] на конкретной таблице в базе данных MySQL, скажем, та, которая имеет 113 000 строк, запрос занимает приблизительно 2 секунды для возврата данных. В PostgreSQL тот же самый запрос на той же таблице занимает почти 10 секунд.

Точно так же у меня есть другая таблица с меньшим количеством строк (88,000), и это хуже! MySQL занимает 1,3 секунды, PostgreSQL занимает 30 секунд!

Это то, что я могу ожидать от PostgreSQL или являюсь там чем-то, что я могу сделать для создания его лучше?

Моей ОС является XP, и я выполняю двойной код на 2.7 ГГц с поршнем на 3 ГБ. База данных MySQL является версией 5.1, под управлением стандартом запаса. База данных PostgreSQL является версией 8.4, и я отредактировал конфигурацию следующим образом: shared_buffers = 128 МБ effective_cache_size = 512 МБ

Спасибо!

Вот структура второй таблицы, которая имеет приблизительно 88 000 строк:

CREATE TABLE nodelink
(
  nodelinkid serial NOT NULL,
  workid integer NOT NULL,
  modifiedbyid integer,
  tabulardatasetid integer,
  fromnodeid integer,
  tonodeid integer,
  materialid integer,
  componentsubtypeid integer,
  crosssectionid integer,
  "name" character varying(64) NOT NULL,
  description character varying(256) NOT NULL,
  modifiedbyname character varying(64) NOT NULL, -- Contains the values from the old engine's ModifiedBy field, since they don't link with any user
  linkdiameter double precision NOT NULL DEFAULT 0, -- The diameter of the Link
  height double precision NOT NULL,
  width double precision NOT NULL,
  length double precision NOT NULL,
  roughness double precision NOT NULL,
  upstreaminvert double precision NOT NULL,
  upstreamloss double precision NOT NULL,
  downstreaminvert double precision NOT NULL,
  downstreamloss double precision NOT NULL,
  averageloss double precision NOT NULL,
  pressuremain double precision NOT NULL,
  flowtogauge double precision NOT NULL,
  cctvgrade double precision NOT NULL,
  installdate timestamp without time zone NOT NULL,
  whencreated timestamp without time zone NOT NULL,
  whenmodified timestamp without time zone NOT NULL,
  ismodelled boolean NOT NULL,
  isopen boolean NOT NULL,
  shapenative geometry,
  shapewgs84 geometry,
  CONSTRAINT nodelink_pk PRIMARY KEY (nodelinkid),
  CONSTRAINT componentsubtype_nodelink_fk FOREIGN KEY (componentsubtypeid)
      REFERENCES componentsubtype (componentsubtypeid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT crosssection_nodelink_fk FOREIGN KEY (crosssectionid)
      REFERENCES crosssection (crosssectionid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fromnode_nodelink_fk FOREIGN KEY (fromnodeid)
      REFERENCES node (nodeid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT material_nodelink_fk FOREIGN KEY (materialid)
      REFERENCES material (materialid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT tabulardataset_nodelink_fk FOREIGN KEY (tabulardatasetid)
      REFERENCES tabulardataset (tabulardatasetid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT tonode_nodelink_fk FOREIGN KEY (tonodeid)
      REFERENCES node (nodeid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT user_nodelink_fk FOREIGN KEY (modifiedbyid)
      REFERENCES awtuser (userid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT work_modellink_fk FOREIGN KEY (workid)
      REFERENCES "work" (workid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE nodelink OWNER TO postgres;
COMMENT ON TABLE nodelink IS 'Contains all of the data that describes a line between any two nodes.';
COMMENT ON COLUMN nodelink.modifiedbyname IS 'Contains the values from the old engine''s ModifiedBy field, since they don''t link with any user';
COMMENT ON COLUMN nodelink.linkdiameter IS 'The diameter of the Link';

Я играл немного больше с избранным оператором. Если я просто "Выбираю NodeLinkID из NodeLink", запрос намного более быстр - меньше, чем секунда для получения 88 000 строк. Если я действительно "Выбираю NodeLinkID, shapenative от NodeLink", запрос занимает много времени - приблизительно 8 секунд. Это проливает какой-либо свет на то, что я делаю неправильно?


Больше результатов:

CREATE INDEX nodelink_lengthIDX на nodelink (длина);

проанализируйте nodelink

- Выполнение запроса: ВЫБЕРИТЕ * ИЗ nodelink, ГДЕ Длина МЕЖДУ 0 И 3.983 Общими количествами запрашивает время выполнения: 3 109 мс. Получены 10 000 строк.

- Выполнение запроса: ВЫБЕРИТЕ nodelinkID ИЗ nodelink, ГДЕ Длина МЕЖДУ 0 И 3.983 Общими количествами запрашивает время выполнения: 125 мс. Получены 10 000 строк.

В MySQL в первом запросе выполняют приблизительно 120 мс, во втором выполняют приблизительно 0,02 мс.



Разрешение вопроса:

Хорошо люди, кажется, что это был весь шторм в чайной чашке...

mjy имел его правильный:

"Как Вы измеряли те синхронизации - в Вашем приложении или соответствующих интерфейсах командной строки?"

Для тестирования этой теории я соединил простое консольное приложение, которое выполнило тот же запрос на дб MySQL и базу данных PGSQL. Вот вывод:

Running MySQL query: [SELECT * FROM l_model_ldata]
MySQL duration = [2.296875]
Running PGSQL query: [SELECT * FROM nodelink]
PGSQL duration = [2.875]

Таким образом, результаты сопоставимы. Кажется, что pgadmin инструмент, который идет с postgreSQL, является довольно медленным. Благодаря всем для их предложений и помощи!

mjy, если Вы хотите отправить ответ, я могу отметить его как корректный ответ для дальнейшего использования.

6
задан Community 23 May 2017 в 12:13
поделиться

6 ответов

Here is a useful article about tuning Postgres- It has definitions and a bit of tips.

This performance tuning article offers a pretty decent overview with some specifics methods of optimization.

2
ответ дан 17 December 2019 в 18:16
поделиться

PostgreSQL использует архитектуру MVCC, что означает, что он использует более сложный формат для хранения данных на диске, чем MySQL. Это медленнее при одиночном доступе и быстрее при многопользовательском доступе.

а) проверьте, очищены ли ваши таблицы - см. Инструкцию VACUUM. б) использовать индексы - PostgreSQL имеет больший репертуар индексов, чем MySQL, поэтому используйте его - есть индексы GiST, GIN.

0
ответ дан 17 December 2019 в 18:16
поделиться

Похоже, вы страдаете фрагментацией. У вас много обновлений без вакуума? Обновляете ли вы индексированные столбцы, чтобы не использовались HOT-обновления?

Каков результат select relpages, reltuples из pg_class, где relname = 'nodelink' . Это покажет вам, на скольких дисковых страницах хранятся ваши кортежи.

@Pavel: PostgreSQL определенно более гибок. индексы, но индекс не поможет в этом случае, поскольку он выбирает все в таблице.

Многие таблицы содержат сотни тысяч строк, поэтому мне нужно помнить о производительности.

Это не особо большие таблицы ...

Это то, чего я могу ожидать от PostgreSQL, или я могу что-то сделать, чтобы сделать его лучше?

... так что, вероятно, вы что-то делаете не так.

0
ответ дан 17 December 2019 в 18:16
поделиться

Были ли у вас также ГИС-функции в MySQL? IIRC, это означает, что вы использовали MyISAM, а не менеджер хранения с поддержкой транзакций, что означает, что вы на самом деле не сравниваете яблоки с яблоками.

Также, ваше приложение на самом деле когда-нибудь сделает это? Полностью безоговорочный выбор всех строк? Если нет, то вы лучше смотрите на производительность тех вещей, которые вы на самом деле собираетесь делать, что, вероятно, будет включать в себя, по крайней мере, ГДЕ пункты. (хотя это, конечно, также не может быть справедливо сравнимо с небезопасной не транзакционной системой)

.
1
ответ дан 17 December 2019 в 18:16
поделиться

Если у вас есть таблица, содержащая сотни (не говоря уже о сотнях тысяч) записей, то какая у вас возможная причина для выполнения запроса SELECT * FROM? Возможно, вам стоит подумать о том, какие данные вы на самом деле запрашиваете, и как получить только соответствующие строки из БД.

.
0
ответ дан 17 December 2019 в 18:16
поделиться

Для нормальной таблицы из 100000 строк это очень долго, поэтому я думаю, что есть проблема в PostGIS, а не в PostgreSQL. Попробуйте получить все строки без шаблонов и столбцов shapewgs84 - если это намного быстрее, то, похоже, PostGIS отвечает за замедление.

.
0
ответ дан 17 December 2019 в 18:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: