performance vamos dormir mais?
-
Upload
tdc-globalcode -
Category
Education
-
view
219 -
download
2
Transcript of performance vamos dormir mais?
![Page 1: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/1.jpg)
Performance vamos dormir mais!
![Page 2: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/2.jpg)
Marcelo Cajueiro• 5 anos trabalhando com Ruby on Rails
• Engenheiro e líder no Enjoei =P
• Não toco nenhum instrumento
• Nick no chat da uol: tatuado_25_na_cam !
• http://cajueiro.me
![Page 3: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/3.jpg)
Disclaimer
![Page 4: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/4.jpg)
(�°□°��� ���)
![Page 5: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/5.jpg)
![Page 6: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/6.jpg)
Barba + Relógio = Maior confiança 1
1 Fonte: broscience (papo de homem - http://goo.gl/ZzyKup)
![Page 7: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/7.jpg)
![Page 8: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/8.jpg)
Tarot da Startup
![Page 9: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/9.jpg)
![Page 10: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/10.jpg)
![Page 11: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/11.jpg)
![Page 12: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/12.jpg)
![Page 13: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/13.jpg)
![Page 14: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/14.jpg)
![Page 15: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/15.jpg)
![Page 16: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/16.jpg)
![Page 17: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/17.jpg)
![Page 18: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/18.jpg)
![Page 19: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/19.jpg)
![Page 20: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/20.jpg)
![Page 21: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/21.jpg)
![Page 22: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/22.jpg)
![Page 23: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/23.jpg)
![Page 24: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/24.jpg)
![Page 25: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/25.jpg)
![Page 26: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/26.jpg)
![Page 27: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/27.jpg)
Réplica no banco de dados
![Page 28: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/28.jpg)
gem 'octopus'
class Badge < ActiveRecord::Base replicated_modelend
Badge.where(user_id: 1) # usa réplica
@user = User.using(:shard1).find_by_name("Joao")
PS.: use com sabedoria.
![Page 29: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/29.jpg)
Rake tasks & réplica
$ DATABASE_URL=postgresql://replica_url rake reports:all
![Page 30: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/30.jpg)
![Page 31: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/31.jpg)
para emailsSidekiq::Extensions::DelayedMailer. sidekiq_options queue: :read_only_default
InviteMailer.delay.new_invite
![Page 32: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/32.jpg)
para workersclass ReportWorker include Sidekiq::Worker
sidekiq_options queue: :read_only_defaultend
![Page 33: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/33.jpg)
$ DATABASE_URL="postgresql://replica_url" sidekiq -c 10 -q read_only_default,2
![Page 34: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/34.jpg)
Queries N+1
http://goo.gl/2j191w 2
2 http://blog.arkency.com/2013/12/rails4-preloading/
![Page 35: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/35.jpg)
Usuário seguindo
outros usuários
![Page 36: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/36.jpg)
class User has_many :user_follows
has_many :followers, through: :user_follows, class_name: 'User', foreign_key: 'follower_id'
has_many :following, through: :user_follows, class_name: 'User', foreign_key: 'user_id'end
![Page 37: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/37.jpg)
class UserFollow belongs_to :user belongs_to :follower, class_name: "User"end
![Page 38: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/38.jpg)
![Page 39: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/39.jpg)
Uma query por usuárioUser.limit(10).each do |user| # Eu estou seguindo esse usuário? if current_user.following.where(id: user.id).exists? # imprime o botão "deixar de seguir" else # imprime o botão "seguir" endend
A solução mais simples geralmente não é a mais performática.
![Page 40: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/40.jpg)
Salvando os ids de quem eu sigo# E se eu estiver seguindo 90mil usuários?following_ids = current_user.following_ids
User.limit(10).each do |user| if following_ids.include?(user.id) # imprime o botão "deixar de seguir" else # imprime o botão "seguir" endend
![Page 41: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/41.jpg)
Pegando os ids que estou listando e vendo quem eu sigo
![Page 42: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/42.jpg)
users = User.limit(10)user_ids = users.map(&:id) # pluck? no :)
following_ids = current_user. following.where(id: user_ids).pluck(:id)
users.each do |user| if following_ids.include?(user.id) # imprime o botão "deixar de seguir" else # imprime o botão "seguir" endend
![Page 43: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/43.jpg)
Fine tune
![Page 44: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/44.jpg)
Com INNER JOINfollowing_ids = current_user. following.where(id: user_ids).pluck(:id)
SELECT "users"."id"FROM "users"INNER JOIN "user_follows" ON "users"."id" = "user_follows"."user_id"WHERE "user_follows"."follower_id" = 1
![Page 45: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/45.jpg)
Sem INNER JOINfollowing_ids = UserFollow. where(follower_id: current_user.id). pluck(:user_id)
SELECT "user_follows"."user_id"FROM "user_follows"WHERE "user_follows"."follower_id" = 1
Nem sempre o que o Rails tem pronto é o melhor.
![Page 46: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/46.jpg)
gem 'bullet'
Chata! Alert, honeybadger, airbrake, slack, etc.
![Page 47: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/47.jpg)
gem 'rack-mini-profiler'
![Page 48: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/48.jpg)
gem 'newrelic_rpm'
localhost:3000/newrelic
![Page 49: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/49.jpg)
![Page 50: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/50.jpg)
Dashboard• data da primeira compra
• data da última compra
• número de compras
• total gasto
• categorias compradas
• marcas compradas
![Page 51: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/51.jpg)
Informações triviais sozinhasclass User def first_purchase_at orders.minimum(:sold_at) end
def last_purchase_at orders.maximum(:sold_at) end
def purchases_count orders.count endend
![Page 52: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/52.jpg)
Informações triviais sozinhasclass User def purchases_total_price orders.sum(:price) end
def purchased_brands purchased_products.pluck(:brand).uniq end
def purchased_brands purchased_products.pluck(:category).uniq endend
![Page 53: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/53.jpg)
6 consultasuser.orders.minimum(:sold_at)user.orders.maximum(:sold_at)user.orders.countuser.orders.sum(:price)user.purchased_products.pluck(:brand).uniquser.purchased_products.pluck(:category).uniq
![Page 54: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/54.jpg)
SQL + Ruby aggregationpurchases = user.orders. order(sold_at: :desc). joins(:product).select( "orders.sold_at", "orders.price", "products.brand", "products.category" ).to_a
![Page 55: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/55.jpg)
SQL + Ruby aggregationpurchases.sum(&:price)purchases.map(&:brand).uniqpurchases.map(&:category).uniqpurchases.first.sold_atpurchases.last.sold_atpurchases.count
![Page 56: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/56.jpg)
SQL aggregationpurchases = user.orders.select( "max(orders.sold_at) AS last_purchased_at", "min(orders.sold_at) AS first_purchased_at", "sum(orders.price) AS total_price", "count(orders.id) AS total").to_a.first
![Page 57: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/57.jpg)
SQL aggregation# Query 1purchases.total_pricepurchases.last_purchased_atpurchases.first_purchased_atpurchases.total
# Query 2user.purchased_products.pluck('DISTINCT(brand)')
# Query 3user.purchased_products.pluck('DISTINCT(category_id)')
![Page 58: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/58.jpg)
Opções
1 - todas as informacões em queries separadas
2 - uma query com todos os dados separados e calculando com ruby
3 - uma query com os campos calculados e outras duas para o restante
![Page 59: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/59.jpg)
Benchmark 3
3 https://github.com/evanphx/benchmark-ips
![Page 60: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/60.jpg)
Calculating ------------------------------------- queries separadas 3.000 i/100ms cálculo SQL + queries 8.000 i/100ms SQL + cálculo ruby 1.000 i/100ms-------------------------------------------------
queries separadas 46.789 (± 8.5%) i/s - 234.000 cálculo SQL + queries 81.732 (± 9.8%) i/s - 408.000 SQL + cálculo ruby 2.314 (± 0.0%) i/s - 12.000
Comparison: cálculo SQL + queries: 81.7 i/s queries separadas: 46.8 i/s - 1.75x slower SQL + cálculo ruby: 2.3 i/s - 35.32x slower
![Page 61: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/61.jpg)
Mais um exemplophotos.order('CASE WHEN selected = true THEN 0 ELSE COALESCE(position, 0) + 1 END')
Ouphotos.sort_by do |photo| if photo.selected? 0 else photo.position.to_i + 1 endend
![Page 62: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/62.jpg)
Calculating ------------------------------------- SQL 1.000 i/100ms Array 1.000 i/100ms------------------------------------------------- SQL 1.054k (± 8.1%) i/s - 5.074k Array 95.344 (± 9.4%) i/s - 468.000
Comparison: SQL: 1053.8 i/s Array: 95.3 i/s - 11.05x slower
![Page 63: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/63.jpg)
Mais sobre ordenação
![Page 64: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/64.jpg)
Ordenação na query + limitEXPLAIN SELECT * FROM messagesWHERE user_id = 1ORDER BY id DESC LIMIT 10
Limit (cost=539.60..539.63 rows=10 width=115) -> Sort (cost=539.60..539.94 rows=136 width=115) Sort Key: id -> Bitmap Heap Scan on messages (cost=5.49..536.67 rows=136 width=115)
Recheck Cond: (user_id = 1) -> Bitmap Index Scan on index_messages_on_user_id (cost=0.00..5.45 rows=136 width=0)
Index Cond: (user_id = 1)
![Page 65: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/65.jpg)
Usando índice com ordenaçãoCREATE INDEX index_messages_ordered_on_user_id ON messages (user_id, id DESC)
Limit (cost=0.43..40.78 rows=10 width=115) -> Index Scan using index_messages_ordered_on_user_id on messages (cost=0.43..549.14 rows=136 width=115)
Index Cond: (user_id = 1)
![Page 66: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/66.jpg)
![Page 67: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/67.jpg)
Cache• Fragment
• Russian doll
• Rack
• HTTP
Speed Up Your Rails App by 66% - The Complete Guide to Rails Caching 4
4 From Nate Berkopec
![Page 68: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/68.jpg)
gem 'identity_cache'
class Product < ActiveRecord::Base include IdentityCache
has_many :photos belongs_to :category
cache_has_many :photos cache_belongs_to :categoryend
product = Product.fetch(1)product.fetch_photosproduct.fetch_category
![Page 69: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/69.jpg)
class Photo < ActiveRecord::Base include IdentityCache
cache_index :imageable_type, :imageable_idend
class Product < ActiveRecord::Base def cached_images Photo. fetch_by_imageable_type_and_imageable_id( 'Product', id ) endend
![Page 70: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/70.jpg)
Counter cache• Implementação do Railsclass Order < ActiveRecord::Base belongs_to :customer, counter_cache: trueend
class Customer < ActiveRecord::Base has_many :ordersend
@customer.orders.size
@customer.orders.count
![Page 71: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/71.jpg)
Counter cachegem 'counter_culture'
class Product < ActiveRecord::Base belongs_to :sub_category
counter_culture :category, :column_name => Proc.new { |model| model.special? ? 'special_count' : nil }end
@category.special_count
![Page 72: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/72.jpg)
Paginação• usar o counter cache para calcular a numeração
• remover a numeração das páginascurrent_user. followers. paginate(per_page: 10, page: params[:page], total_entries: current_user.followers_count)
![Page 73: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/73.jpg)
Remover locks pessismistas desnecessários
Comment.lock.find(1).destroy
comment = Comment.find(1)comment.with_lock do comment.destroy!end
![Page 74: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/74.jpg)
Admin no servidor do usuário final
• Admin é sempre mais lento
• Tem Relatórios
• Cheio de ações demoradas
Boa solução
• Proxy reverso
![Page 75: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/75.jpg)
Lazy load na interface• Por que carregar os comentários na ação principal?
• Por que carregar os produtos relacionados na ação principal?
• ...
![Page 76: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/76.jpg)
Migration sem lock na tabelaclass AddIndexToMessages < ActiveRecord::Migration disable_ddl_transaction!
def change add_index :messages, :user_id, algorithm: :concurrently endend
![Page 77: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/77.jpg)
![Page 78: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/78.jpg)
jobs.lever.co/enjoei
![Page 79: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/79.jpg)
Muito obrigado!Sugestões? Perguntas?
![Page 80: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/80.jpg)
Referência das imagens• https://en.wikipedia.org/wiki/Rider-Waitetarotdeck
• http://www.maxi-geek.com/2015/05/the-flash-vs-superman-who-will-bleed.html
• https://sobeso.com/beating-creative-block
• http://www.motherhoodcenter.com/sleep-coach/
• http://9to5mac.com/2015/03/06/sources-offer-hands-on-apple-watch-details-battery-life-unannounced-features-and-more/
![Page 81: performance vamos dormir mais?](https://reader030.fdocumentos.com/reader030/viewer/2022020119/58f16f291a28ab966e8b4595/html5/thumbnails/81.jpg)
E mais referência das imagens• http://www.jackiealpers.com/mysteries-rituals/the-world-
photograph-of-a-man-holding-a-tarot-card-by-jackie-alpers-728153.html
• http://thezt2roundtable.com/search/5/?c=3&mid=3525512&month=4&year=2015
• http://www.fanpop.com/clubs/jaime-lannister/images/37085417/title/jaime-tyrion-lannister-photo/7