Postgres i indeksy

cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Mam tabelę, która zawiera ok. 150 tysięcy rekordów.
Jej struktura to ID, kolumna z jakimś numerem seryjnym i do tego 2-3 kolumny z jakimiś tekstami/opisami (niezbyt długimi - po kilkadziesiąt znaków).

Ważne - tabela jest stworzona, zapełniona i potem tylko odpytywana. Odpytywanie będzie miało miejsce jedynie po numerze seryjnym - czyli użytkownik wprowadza ten numer, a SQL ma zwrócić stringi do niego przypisane. Dlatego (wprawdzie 150 tys to nie jest jakaś kosmiczna ilość) aż się prosi o założenie indeksu na kolumnie z kodem.

I teraz moje pytanie - jak uważacie, czy lepiej zrobić tą kolumnę jako varchar czy int? Kody mają 6 albo 7 znaków (jedynie cyfry - dlatego można to zapisać w postaci liczbowej), poza znalezieniem i wyrzuceniem do raportu, nic z tym się nie dzieje, więc z punktu widzenia aplikacji, typ danych kolumny z kodami nie ma żadnego znaczenia. Tutaj chodzi jedynie o to, żeby maksymalnie szybko działało wyszukiwanie.

Wydaje mi się, że lepszą opcją będzie zrobienie tego w postaci numerycznej niż tekstowej, ale chciałem poprosić Was o potwierdzenie, albo wyprowadzenie z błędu. Poszukałem w necie i w oparciu o te informacje także mam wrażenie, że int jest słuszniejszy, ale to może być tak jak z samochodem - kupujesz Focusa i nagle wszędzie widzisz Fordy na ulicach ;)


Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
1

jedynie cyfry - dlatego można to zapisać w postaci liczbowej

Z ciekawości: pesel zapisałbyś jako bigint czy varchar? :-)


edytowany 1x, ostatnio: Patryk27
cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Zależy od potrzeb i innych czynników - czy np. będzie on jakoś walidowany, czy jedynie zapisany w bazie, co będzie się z nim potem działo, w jaki sposób będzie przetwarzany itp., aczkolwiek ponieważ ten PESEL, wprawdzie jest cyfrowy, ale nie będzie traktowany jako liczba, a do tego ma stałą długość, raczej bym się skłaniał do zapisu jako char(11).

Tylko różnica jest taka, że w moim przypadku zależy mi jedynie na tym, żeby szukanie działało jak najsprawniej i żeby najłatwiej było bazie przeszukiwać indeks. Dlatego to może być zapisane w dowolnej postaci, z mojego punktu widzenia nie ma to znaczenia, ale (jak pisałem) z tego co znalazłem, to łatwiej jest przelecieć indeks b-tree na wartościach liczbowych.


edytowany 2x, ostatnio: cerrato
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

wprawdzie jest cyfrowy, ale nie będzie przetwarzany jako liczba

Czy Twoje numery seryjne będą przetwarzane jako liczba? Ponieważ z postu wynika, że nie.

w moim przypadku zależy mi jedynie na tym, żeby szukanie działało jak najsprawniej i żeby najłatwiej było bazie przeszukiwać indeks

Liczby będą minimalnie szybsze, lecz wchodzimy tutaj w teren premature optimization.


cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Nie, to chodzi jedynie o znalezienie odpowiedniej wartości w tabeli i pobranie przypisanych do nich wartości. Przyjmijmy, że mamy tabelę z kolumnami numer katalogowy, producent, model, opis. Użytkownik podaje numer katalogowy, a SQL zwraca producenta, model i opis. Nic się z tym dziać nie będzie, jak napisałem - tabela zostanie jednorazowo zapełniona danymi, a potem będzie tylko odczytywana. I powtarzam - to, czy ten numer seryjny będzie tekstem czy liczbowo dla mnie nie ma żadnego znaczenia, jedynie chodzi o to, żeby założony na tej kolumnie indeks działał jak najsprawniej.


Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
1

jedynie chodzi o to, żeby założony na tej kolumnie indeks działał jak najsprawniej

W takim razie załóż indeks liczbowy.


cerrato
Też tak podejrzewałem, ale wolałem się upewnić. Dzięki :)
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Jeśli to są numery zamówień, to upewnij się że użytkownicy nie mogą sobie nawzajem podglądać nieswoich zamówień.
Bo takie niebezpieczeństwo występuje gdy zamówienie / fv generujesz na podstawie numeru sekwencyjnego.
Można się przed tym zabezpieczyć (np. sprawdzając zawsze też nr klienta pytającego o dane).

cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Nie, to nie są żadne poufne dane, z grubsza chodzi o to, co napisałem 2 posty wyżej. Taki katalog, który na podstawie oznaczenia ma wczytać informacje o przedmiocie. Każdy korzystający z aplikacji ma mieć dostęp do tego bez jakichkolwiek ograniczeń.


abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:8 miesięcy
  • Postów:6610
3

znacznie więcej zyskasz jeśli zamiast indeksu liczbowego założysz indeks na wszystkie kolumny po których będziesz szukał + kolumny, które będziesz wyciągał. W Twoim przypadku to będzie indeks na numer katalogowy, producent, model, opis. Wtedy silnik w ogóle nie będzie musiał odwoływać się do tabeli a skoro insertów i tak nie będzie to nie będzie to miało znaczenia dla wydajności dodawania danych (poza pierwszym)


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
vpiotr
Jeśli założy indeks na wszystkie kolumny tabeli to jaki z tego zysk? Nie będzie czytał stron tabeli, ale będzie czytał strony indeksu.
abrakadaber
abrakadaber
taki, że będą posortowane a dodatkowo po znalezieniu rekordów, których szukasz silnik nie musi skakać do tabeli żeby odczytać pozostałe kolumny. Przecież to podstawy...
vpiotr
To było zwykłe pytanie, nie ma się co obrażać od razu.
cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

No ale wydaje mi się, że jak już baza ustali ID, dla którego ma pobrać dane, to później już ich odczyt z tabeli to formalność. Największym problemem jest przeszukanie tych 100 tysięcy wpisów - bez indeksów to trzeba przelecieć przez wszystkie po kolei i tego chciałem uniknąć. Pytanie - czy indeksy na wszystkich kolumnach mają sens? Jeśli tak, to nie ma problemu i mogę tak zrobić, tylko jakoś nie jestem przekonany, czy to coś da.


Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

Nie do końca taka formalność: jeśli indeks w całości pokrywa spis kolumn, o które pytasz w klauzuli select (czyli jest to tzw. covering index), silnik bazy nie musi męczyć się z wczytywaniem danych z rzeczywistej tabeli (w przypadku Postgresa nazywanej heap) i opiera całe zapytanie wyłącznie o dane z indeksu.


edytowany 2x, ostatnio: Patryk27
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1
edytowany 1x, ostatnio: vpiotr
cerrato
dzięki, ale dokładnie ten sam link wrzucił piętro wyżej Patryk ;)
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:dzień
  • Postów:2370
1

Skoro to tylko read-only, to możesz zrobić sobie challenge na nowy rok i zrobić szybką armatę jako rozszerzenie postgresa -> funkcja w C.
https://www.postgresql.org/docs/12/xfunc-c.html

Prosta hashmapa inicjalizowana tymi 150k wpisami. Nie jest to proste (użycie i utrzymanie) ani szybkie (implementacji), ale wywołania powinny być mega szybkie (odpadną operacje I/O na czytanie indeksu/tabeli, czy locki mające zapewnić spójność danych w ramach transakcji).

Propozycja w ramach pobudzenia wyobraźni ;-)

cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

@yarel: pomysł może ciekawy, ale totalnie nie mam czasu (ani ochoty i być może umiejętności) na wdrażanie tego w życie. Nie musi to być prędkość szukania rzędu 0,0000023 sekundy, po prostu mam tabelę jedynie do odczytu i chcę ten odczyt maksymalnie przyspieszyć/zoptymalizować. ale nikt z powodu pół sekundy dłuższego czekania nie będzie robić tragedii, nie przesadzajmy :D

No a poza tym trochę nieskromne i nieprawdziwe by było twierdzenie, że ja sobie sam napiszę coś lepiej, niż grupa ekspertów, która opracowała mechanizmy tworzenia i obsługi indeksów w Postgresie.


edytowany 1x, ostatnio: cerrato
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:dzień
  • Postów:2370
1

@cerrato: rozumiem brak czasu i sam często wybieram pragmatyczne rozwiązania, zamiast poeksperymentować i zepsuć parę rzeczy ;)

Z innych pomysłów, to można przeorganizować tabelkę względem indeksu:

cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Pomysły i dobre, ale tutaj wychodzimy z przysłowiową armatą na komara. Po pierwsze - dla Postgresa 150k rekordów to nie jest żadna kosmiczna ilość. A po drugie - nie jest to aplikacja dla szpitala, która musi działać w czasie rzeczywistym, więc pól sekundy mniej czy więcej czekania nie robi różnicy. Po prostu - skoro można niewielkim nakładem pracy dołożyć indeks i przyspieszyć pracę, więc czemu z tego nie skorzystać? Ale jakbym miał poświęcić na to więcej czasu to bez przesady, nie ma co przeginać.


neves
  • Rejestracja:prawie 22 lata
  • Ostatnio:około 5 godzin
  • Lokalizacja:Kraków
  • Postów:1114
2
yarel napisał(a):

Skoro to tylko read-only, to możesz zrobić sobie challenge na nowy rok i zrobić szybką armatę jako rozszerzenie postgresa -> funkcja w C.
https://www.postgresql.org/docs/12/xfunc-c.html

Prosta hashmapa inicjalizowana tymi 150k wpisami. Nie jest to proste (użycie i utrzymanie) ani szybkie (implementacji), ale wywołania powinny być mega szybkie (odpadną operacje I/O na czytanie indeksu/tabeli, czy locki mające zapewnić spójność danych w ramach transakcji).

Propozycja w ramach pobudzenia wyobraźni ;-)

Chciałbym to zobaczyć czy rzeczywiście udałoby się to zrobić szybciej, w postgressie jest out of the box MVCC czyli locków na czytanie danych nie ma, a jak jest wystarczająco RAMu to i tak tabela cały czas będzie trzymana w pamięci i nie będzie odczytów z dysku. Na dodatek w postgresie mamy również dostępny indeks oparty na hashowaniu jako alternatywa dla btree, także pobicie tego co postgres oferuje może nie być takie proste.

Także indeks pokrywający albo indeks klastrowy z kolumną typu int to najlepsze rozwiązanie.


edytowany 1x, ostatnio: neves
hauleth
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:7 dni
1

Będziesz szukał po tych numerach seryjnych czy nie? Jeśli tak to lepiej string i B-Tree, jeśli nie to albo indeks liczbowy (jeśli wiodące 0 nie mają znaczenia) albo string i hash-index.

Poza tym w PSQL bardziej idiomatyczne jest używanie TEXT zamiast VARCHAR.


cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

@hauleth: tak, jak napisałem kilka postów wyżej - https://4programmers.net/Forum/1644477, każdy rekord składa się z numeru seryjnego oraz kilku stringów z opisem przypisanych do tego numeru. Tabela jest jedynie do odczytu, jedyna forma szukania to po numerze seryjnym. Żeby usprawnić wyszukiwanie, na kolumnie będącej kluczem szukania chcę założyć indeks (plus może jak inni radzili - także na kolumnach zawierających zwracane dane).
Dla mnie nie ma znaczenia, czy kolumna z numerem seryjnym będzie miała postać tekstową czy liczbową, chodzi jedynie o to, jaką łatwiej będzie bazie przeszukać w odpowiedzi na mój SELECT FROM.


edytowany 1x, ostatnio: cerrato
hauleth
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:7 dni
1

jedyna forma szukania to po numerze seryjnym

Chodziło mi o to czy jeśli masz nr seryjny 12345 i ktoś wpisze 123 to ma mu się również wyświetlić ten wpis. Jeśli tak, to tekstowa się lepiej sprawdzi, bo łatwiej zrobić zapytanie ILIKE.


cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
1

Nie, nie będzie żadnego LIKE ani dopasowywania. Aplikacja prześle do SQL gotowy i kompletny kod, który albo zostanie znaleziony, albo nie ;) Dlatego (moim zdaniem) sprawniej przejdzie szukanie po liczbach.


hauleth
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:7 dni
1

Wtedy tak. Po prawdzie jeśli będzie tam hash indeks to czasy powinny być praktycznie identyczne, aczkolwiek jeśli wiodące zera nie są problemem, masz pewność, że nie pojawią się litery, oraz, że nie będzie trzeba szukać cząstkowo, to liczby będą lepsze.


cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Wiodące zera sobie dodam już po otrzymaniu odpowiedzi z SQL, na etapie wypluwania treści do raportu.
W takim razie chyba sprawa ogarnięta, dzięki za pomoc :)

P.S. a co @hauleth i @Marcin.Miga sądzicie o pomyśle podanym wcześniej, żeby nie zakładać indeksu tylko na kolumnie z numerem seryjnym (po której będę wyszukiwać), ale żeby także indeksować kolumny zawierające zwracane treści?


hauleth
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:7 dni
1

Indeksować bez sensu IMHO. Jak już to zrób indeks zawierający te pola. Masz INCLUDE przy tworzeniu indeksu, który dokładnie do tego służy. Możesz też zaktualizować statystyki planera zaraz jak wciśniesz wszystkie dane, co może pozwolić planerowi trochę jeszcze przyspieszyć zapytania.


cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Tylko pytanie, czy dodanie do tego indeksu dodatkowych pól nie spowoduje, że taki indeks będzie się wolniej przeszukiwać, niż jakby zawierał jedynie kolumnę z numerem seryjnym i nic poza tym?


vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Po to wlasnie jest ten INCLUDE zeby wyszukiwanie nie bylo wolniejsze. A jak jest w rzeczywistosci to musialbys przetestowac.

cerrato
nie jest wolniejsze != jest szybsze ;) Nie wiem, czy jest sens aż tak sprawę udziwniać.
BG
  • Rejestracja:prawie 6 lat
  • Ostatnio:4 dni
  • Postów:289
1

Na SQL się specjalnie nie znam, ale 150 tysięcy rekrodów to dla Postgresa chyba śmieszna baza...

Kopiuj
=> select count(*) from mysecretdata;
  count  
---------
 9051215
(1 row)

explain analyze select * from mysecretdata where id = 'XYZ-20191111-074004-638-12-whatever-sth-xy';
                                                             QUERY PLAN                                                             
------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using mysecretdata_pkey on mysecretdata  (cost=0.56..8.58 rows=1 width=235) (actual time=0.482..0.484 rows=1 loops=1)
   Index Cond: (id = 'XYZ-20191111-074004-638-12-whatever-sth-xy'::text)
 Planning Time: 0.134 ms
 Execution Time: 0.559 ms
(4 rows)
cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:2 dni
  • Lokalizacja:Poznań
  • Postów:8794
0

Owszem, jak na "porządnego" SQL to 150 tysięcy nie jest jakąś zawrotną ilością, ale skoro można praktycznie zerowym nakładem to przyspieszyć, to głupio by było nie skorzystać ;)

i taka uwaga - to nie jest cała baza, a jedynie jedna z tabel w tej bazie. Cała baza będzie znacznie większa, ponadto będą na niej cały czas przeprowadzane operacje zapisu.


edytowany 1x, ostatnio: cerrato
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)